Merge branch 'ui' into for_webui

This commit is contained in:
Sakamoto Shiina
2024-09-15 17:26:36 +09:00
12 changed files with 257 additions and 36 deletions

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,7 @@ const resources = {
en: { translation: translation_en },
ja: { translation: translation_ja },
ko: { translation: translation_ko },
zh_Hant: { translation: translation_zh_Hant },
"zh-Hant": { translation: translation_zh_Hant },
};
i18n

View File

@@ -10,6 +10,8 @@ export const App = () => {
return (
<div className={styles.container}>
<StartPythonFacadeComponent />
<UiLanguageController />
<ConfigPageCloseTrigger />
<ConfigPage />
<MainPage />
</div>
@@ -25,6 +27,9 @@ import { useMicThreshold } from "@logics_configs/useMicThreshold";
import { useSpeakerThreshold } from "@logics_configs/useSpeakerThreshold";
import { useEnableAutoClearMessageBox } from "@logics_configs/useEnableAutoClearMessageBox";
import { useSendMessageButtonType } from "@logics_configs/useSendMessageButtonType";
import { useUiLanguage } from "@logics_configs/useUiLanguage";
import { useSelectableLanguageList } from "@logics/useSelectableLanguageList";
const StartPythonFacadeComponent = () => {
const { asyncStartPython } = useStartPython();
@@ -39,13 +44,21 @@ const StartPythonFacadeComponent = () => {
const { getSpeakerThreshold, getEnableAutomaticSpeakerThreshold } = useSpeakerThreshold();
const { getEnableAutoClearMessageBox } = useEnableAutoClearMessageBox();
const { getSendMessageButtonType } = useSendMessageButtonType();
const { getUiLanguage } = useUiLanguage();
const { getSelectableLanguageList } = useSelectableLanguageList();
useEffect(() => {
main_page.setDecorations(true);
if (!hasRunRef.current) {
asyncStartPython().then((result) => {
getUiLanguage();
getSoftwareVersion();
getSelectableLanguageList();
getSelectedMicHost();
getSelectedMicDevice();
getSelectedSpeakerDevice();
@@ -64,5 +77,36 @@ const StartPythonFacadeComponent = () => {
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;
};
import { useVolume } from "@logics/useVolume";
import { useStore_IsOpenedConfigPage } from "@store";
const ConfigPageCloseTrigger = () => {
const { currentIsOpenedConfigPage } = useStore_IsOpenedConfigPage();
const {
currentMicThresholdCheckStatus,
volumeCheckStop_Mic,
currentSpeakerThresholdCheckStatus,
volumeCheckStop_Speaker,
} = useVolume();
useEffect(() => {
if (currentIsOpenedConfigPage === false) {
if (currentMicThresholdCheckStatus.data === true) volumeCheckStop_Mic();
if (currentSpeakerThresholdCheckStatus.data === true) volumeCheckStop_Speaker();
}
}, [currentIsOpenedConfigPage]);
return null;
};

View File

@@ -12,8 +12,8 @@ export const SettingBox = () => {
return <Device />;
// case "others":
// return <Others />;
// case "appearance":
// return <Appearance />;
case "appearance":
return <Appearance />;
// case "about_vrct":
// return <AboutVrct />;

View File

@@ -1,24 +1,24 @@
import clsx from "clsx";
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 { useStore_SelectedMicDevice, useStore_MicDeviceList } from "@store";
export const Appearance = () => {
const { t } = useTranslation();
const { currentSelectedMicDevice, updateSelectedMicDevice } = useStore_SelectedMicDevice();
const { currentMicDeviceList } = useStore_MicDeviceList();
// const { currentSelectedMicDevice, updateSelectedMicDevice } = useStore_SelectedMicDevice();
// const { currentMicDeviceList } = useStore_MicDeviceList();
const {
DropdownMenuContainer,
SliderContainer,
CheckboxContainer,
SwitchboxContainer,
EntryContainer,
ThresholdContainer,
RadioButtonContainer,
DeeplAuthKeyContainer,
MessageFormatContainer,
WordFilterContainer,
ActionButtonContainer,
// SliderContainer,
// CheckboxContainer,
// SwitchboxContainer,
// EntryContainer,
// ThresholdContainer,
// RadioButtonContainer,
// DeeplAuthKeyContainer,
// MessageFormatContainer,
// WordFilterContainer,
// ActionButtonContainer,
} = useSettingBox();
const selectFunction = (selected_data) => {
@@ -34,8 +34,13 @@ export const Appearance = () => {
return (
<>
<DropdownMenuContainer dropdown_id="mic_host" label="Mic Host/Driver" desc="description" selected_id="b" list={{a: "A", b: "B", c: "C"}} />
<DropdownMenuContainer dropdown_id="mic_device" label="Mic Device" desc="description" selected_id={currentSelectedMicDevice.data} list={currentMicDeviceList} selectFunction={selectFunction} state={currentSelectedMicDevice.state} />
<UiLanguageContainer
/>
{/* <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"/>
<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`)}/>
<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>
);
};

View File

@@ -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);
}

View File

@@ -1,11 +1,13 @@
import { useTranslation } from "react-i18next";
import { language_list } from "@data";
import { useSelectableLanguageList } from "@logics/useSelectableLanguageList";
import styles from "./LanguageSelector.module.scss";
import { LanguageSelectorTopBar } from "./language_selector_top_bar/LanguageSelectorTopBar";
export const LanguageSelector = ({ id }) => {
const { t } = useTranslation();
const { currentSelectableLanguageList, updateSelectableLanguageList } = useSelectableLanguageList();
const languageTitles = {
"your_language": t("selectable_language_window.title_your_language"),
@@ -25,7 +27,7 @@ export const LanguageSelector = ({ id }) => {
}, {});
};
const groupedLanguages = groupLanguagesByFirstLetter(language_list);
const groupedLanguages = groupLanguagesByFirstLetter(currentSelectableLanguageList);
return (
<div className={styles.container}>

View 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,
};
};

View File

@@ -1,6 +1,7 @@
import { arrayToObject } from "@utils/arrayToObject";
import { useMainFunction } from "./useMainFunction";
import { useMessage } from "./useMessage";
import { useSelectableLanguageList } from "./useSelectableLanguageList";
import { useVolume } from "./useVolume";
import { useSoftwareVersion } from "@logics_configs/useSoftwareVersion";
@@ -15,6 +16,8 @@ import { useSpeakerThreshold } from "@logics_configs/useSpeakerThreshold";
import { useEnableAutoClearMessageBox } from "@logics_configs/useEnableAutoClearMessageBox";
import { useSendMessageButtonType } from "@logics_configs/useSendMessageButtonType";
import { useUiLanguage } from "@logics_configs/useUiLanguage";
export const useReceiveRoutes = () => {
const {
@@ -23,6 +26,8 @@ export const useReceiveRoutes = () => {
updateTranscriptionReceiveStatus,
} = useMainFunction();
const { updateSelectableLanguageList } = useSelectableLanguageList();
const {
updateSentMessageLogById,
addSentMessageLog,
@@ -43,6 +48,8 @@ export const useReceiveRoutes = () => {
const { updateEnableAutoClearMessageBox } = useEnableAutoClearMessageBox();
const { updateSendMessageButtonType } = useSendMessageButtonType();
const { updateUiLanguage } = useUiLanguage();
const {
updateVolumeVariable_Mic,
@@ -59,6 +66,7 @@ export const useReceiveRoutes = () => {
"/controller/callback_enable_transcription_receive": updateTranscriptionReceiveStatus,
"/controller/callback_disable_transcription_receive": updateTranscriptionReceiveStatus,
"/controller/list_language_and_country": updateSelectableLanguageList,
"/config/version": updateSoftwareVersion,
@@ -79,10 +87,10 @@ export const useReceiveRoutes = () => {
"/action/check_mic_threshold_energy": updateVolumeVariable_Mic,
"/action/check_speaker_threshold_energy": updateVolumeVariable_Speaker,
"/controller/callback_enable_check_mic_threshold": () => updateMicThresholdCheckStatus(true),
"/controller/callback_disable_check_mic_threshold": () => updateMicThresholdCheckStatus(false),
"/controller/callback_enable_check_speaker_threshold": () => updateSpeakerThresholdCheckStatus(true),
"/controller/callback_disable_check_speaker_threshold": () => updateSpeakerThresholdCheckStatus(false),
"/controller/callback_enable_check_mic_threshold": updateMicThresholdCheckStatus,
"/controller/callback_disable_check_mic_threshold": updateMicThresholdCheckStatus,
"/controller/callback_enable_check_speaker_threshold": updateSpeakerThresholdCheckStatus,
"/controller/callback_disable_check_speaker_threshold": updateSpeakerThresholdCheckStatus,
"/config/enable_auto_clear_message_box": updateEnableAutoClearMessageBox,
"/controller/callback_enable_auto_clear_chatbox": updateEnableAutoClearMessageBox,
@@ -101,7 +109,10 @@ export const useReceiveRoutes = () => {
"/controller/callback_disable_mic_dynamic_energy_threshold": updateEnableAutomaticMicThreshold,
"/config/input_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,
"/action/transcription_send_mic_message": addSentMessageLog,
@@ -112,11 +123,11 @@ export const useReceiveRoutes = () => {
switch (parsed_data.status) {
case 200:
const route = routes[parsed_data.endpoint];
(route) ? route(parsed_data.result) : console.error(`Invalid endpoint: ${parsed_data.endpoint}`);
(route) ? route(parsed_data.result) : console.error(`Invalid endpoint: ${parsed_data.endpoint}\nresult: ${JSON.stringify(parsed_data.result)}`);
break;
case 348:
console.log("from backend:", parsed_data);
console.log(`from backend: %c ${JSON.stringify(parsed_data)}`, style_348);
break;
default:
@@ -126,4 +137,8 @@ export const useReceiveRoutes = () => {
};
return { receiveRoutes };
};
};
const style_348 = [
"color: gray",
].join(";");

View File

@@ -0,0 +1,17 @@
import { useStore_SelectableLanguageList } from "@store";
import { useStdoutToPython } from "@logics/useStdoutToPython";
export const useSelectableLanguageList = () => {
const { asyncStdoutToPython } = useStdoutToPython();
const { currentSelectableLanguageList, updateSelectableLanguageList } = useStore_SelectableLanguageList();
const getSelectableLanguageList = () => {
asyncStdoutToPython("/controller/list_language_and_country");
};
return {
currentSelectableLanguageList,
getSelectableLanguageList,
updateSelectableLanguageList,
};
};

View File

@@ -28,9 +28,13 @@ export const useVolume = () => {
updateMicVolume(payload);
},
currentMicThresholdCheckStatus: currentMicThresholdCheckStatus,
updateMicThresholdCheckStatus: (payload) => updateMicThresholdCheckStatus(payload),
updateMicThresholdCheckStatus: (payload) => {
updateMicThresholdCheckStatus(payload);
if (payload === false) updateMicVolume("0");
},
volumeCheckStart_Speaker: () => {
updateSpeakerVolume("0");
updateSpeakerThresholdCheckStatus(asyncPending);
asyncStdoutToPython("/controller/callback_enable_check_speaker_threshold");
},
@@ -42,7 +46,10 @@ export const useVolume = () => {
updateSpeakerVolume(payload);
},
currentSpeakerThresholdCheckStatus: currentSpeakerThresholdCheckStatus,
updateSpeakerThresholdCheckStatus: (payload) => updateSpeakerThresholdCheckStatus(payload),
updateSpeakerThresholdCheckStatus: (payload) => {
updateSpeakerThresholdCheckStatus(payload);
if (payload === false) updateSpeakerVolume("0");
}
};
};

View File

@@ -96,7 +96,6 @@ const createAsyncAtomWithHook = (initialValue, base_ame) => {
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_TranscriptionSendStatus, useHook: useStore_TranscriptionSendStatus } = createAsyncAtomWithHook(false, "TranscriptionSendStatus");
export const { atomInstance: Atom_TranscriptionReceiveStatus, useHook: useStore_TranscriptionReceiveStatus } = createAsyncAtomWithHook(false, "TranscriptionReceiveStatus");
@@ -109,6 +108,8 @@ export const { atomInstance: Atom_IsOpenedLanguageSelector, useHook: useStore_Is
"IsOpenedLanguageSelector"
);
export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList");
export const { atomInstance: Atom_SelectedPresetTabNumber, useHook: useStore_SelectedPresetTabNumber } = createAtomWithHook(1, "SelectedPresetTabNumber");
export const { atomInstance: Atom_IsOpenedConfigPage, useHook: useStore_IsOpenedConfigPage } = createAtomWithHook(false, "IsOpenedConfigPage");
export const { atomInstance: Atom_SelectedConfigTabId, useHook: useStore_SelectedConfigTabId } = createAtomWithHook("device", "SelectedConfigTabId");
@@ -136,6 +137,17 @@ export const { atomInstance: Atom_SpeakerThreshold, useHook: useStore_SpeakerThr
export const { atomInstance: Atom_EnableAutomaticMicThreshold, useHook: useStore_EnableAutomaticMicThreshold } = createAsyncAtomWithHook(false, "EnableAutomaticMicThreshold");
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({
before: "",
after: "",