diff --git a/locales/en.json b/locales/en.json index 29e25d8c..56835543 100644 --- a/locales/en.json +++ b/locales/en.json @@ -143,6 +143,7 @@ }, "mic_host_device": { "label": "Mic Device", + "label_auto_select": "Auto Select", "label_host": "Host/Driver", "label_device": "Device" }, @@ -175,7 +176,9 @@ "count_desc": "Current registered word count: {{count}}" }, "speaker_device": { - "label": "Speaker Device" + "label": "Speaker Device", + "label_auto_select": "Auto Select", + "label_device": "Device" }, "speaker_dynamic_energy_threshold": { "label_for_automatic": "Speaker Energy Threshold (Current Setting: Automatic)", diff --git a/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.jsx b/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.jsx index 86f811fd..857b1fbb 100644 --- a/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.jsx @@ -24,15 +24,17 @@ export const DropdownMenu = (props) => { }; const dropdown_content_wrapper_class_name = clsx(styles["dropdown_content_wrapper"], { - [styles["is_opened"]]: (currentIsOpenedDropdownMenu === props.dropdown_id) ? true : false + [styles.is_opened]: (currentIsOpenedDropdownMenu === props.dropdown_id) ? true : false, + [styles.is_disabled]: props.is_disabled, }); const dropdown_toggle_button_class_name = clsx(styles["dropdown_toggle_button"], { - [styles["is_loading"]]: (props.state === "loading") ? true : false + [styles.is_loading]: (props.state === "loading") ? true : false, + [styles.is_disabled]: props.is_disabled, }); const arrow_class_names = clsx(styles["arrow_left_svg"], { - [styles["is_opened"]]: (currentIsOpenedDropdownMenu === props.dropdown_id) ? true : false + [styles.is_opened]: (currentIsOpenedDropdownMenu === props.dropdown_id) ? true : false }); const getSelectedText = () => { diff --git a/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.module.scss b/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.module.scss index 0387f420..c6bcbfa6 100644 --- a/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/components/dropdown_menu/DropdownMenu.module.scss @@ -20,6 +20,12 @@ &.is_loading { pointer-events: none; } + &.is_disabled { + pointer-events: none; + .dropdown_selected_text, .arrow_left_svg { + color: var(--dark_550_color); + } + } } .dropdown_selected_text { @@ -37,6 +43,12 @@ &.is_opened { display: block; } + &.is_disabled { + pointer-events: none; + .value_text { + color: var(--dark_550_color); + } + } } .dropdown_content { diff --git a/src-ui/app/config_page/setting_section/setting_box/device/Device.jsx b/src-ui/app/config_page/setting_section/setting_box/device/Device.jsx index 6bfee05f..762b3e52 100644 --- a/src-ui/app/config_page/setting_section/setting_box/device/Device.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/device/Device.jsx @@ -1,3 +1,4 @@ +import clsx from "clsx"; import { useTranslation } from "react-i18next"; import styles from "./Device.module.scss"; import { @@ -12,6 +13,8 @@ export const Device = () => { ); }; +import { useEnableAutoMicSelect } from "@logics_configs/useEnableAutoMicSelect"; + import { useMicHostList } from "@logics_configs/useMicHostList"; import { useSelectedMicHost } from "@logics_configs/useSelectedMicHost"; @@ -26,6 +29,7 @@ import { Switchbox } from "../components/switchbox/Switchbox"; const Mic_Container = () => { const { t } = useTranslation(); + const { currentEnableAutoMicSelect, toggleEnableAutoMicSelect } = useEnableAutoMicSelect(); const { currentSelectedMicHost, setSelectedMicHost } = useSelectedMicHost(); const { currentMicHostList, getMicHostList } = useMicHostList(); const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu(); @@ -35,6 +39,8 @@ const Mic_Container = () => { setSelectedMicHost(selected_data.selected_id); }; + const is_disabled_selector = currentEnableAutoMicSelect.data === true || currentEnableAutoMicSelect.data === "loading"; + const { currentSelectedMicDevice, setSelectedMicDevice } = useSelectedMicDevice(); const { currentMicDeviceList, getMicDeviceList } = useMicDeviceList(); @@ -54,7 +60,6 @@ const Mic_Container = () => { desc: t("config_page.mic_dynamic_energy_threshold.desc_for_manual"), }; } - }; return ( @@ -62,8 +67,17 @@ const Mic_Container = () => {
+ +
+

{t("config_page.mic_host_device.label_auto_select")}

+ +
+
-

{t("config_page.mic_host_device.label_host")}

+

{t("config_page.mic_host_device.label_host")}

{ openListFunction={getMicHostList} state={currentSelectedMicHost.state} style={{ maxWidth: "20rem", minWidth: "10rem" }} + is_disabled={is_disabled_selector} />
-

{t("config_page.mic_host_device.label_device")}

+

{t("config_page.mic_host_device.label_device")}

{ selectFunction={selectFunction_device} openListFunction={getMicDeviceList} state={currentSelectedMicDevice.state} + is_disabled={is_disabled_selector} />
@@ -107,6 +123,7 @@ const Mic_Container = () => {
); }; +import { useEnableAutoSpeakerSelect } from "@logics_configs/useEnableAutoSpeakerSelect"; import { useSpeakerDeviceList } from "@logics_configs/useSpeakerDeviceList"; import { useSelectedSpeakerDevice } from "@logics_configs/useSelectedSpeakerDevice"; @@ -114,6 +131,7 @@ import { useSpeakerThreshold } from "@logics_configs/useSpeakerThreshold"; const Speaker_Container = () => { const { t } = useTranslation(); + const { currentEnableAutoSpeakerSelect, toggleEnableAutoSpeakerSelect } = useEnableAutoSpeakerSelect(); const { currentSelectedSpeakerDevice, setSelectedSpeakerDevice } = useSelectedSpeakerDevice(); const { currentSpeakerDeviceList, getSpeakerDeviceList } = useSpeakerDeviceList(); const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu(); @@ -123,6 +141,8 @@ const Speaker_Container = () => { setSelectedSpeakerDevice(selected_data.selected_id); }; + const is_disabled_selector = currentEnableAutoSpeakerSelect.data === true || currentEnableAutoSpeakerSelect.data === "loading"; + const getLabels = () => { if (currentEnableAutomaticSpeakerThreshold.data === true) { return { @@ -143,7 +163,17 @@ const Speaker_Container = () => {
+ +
+

{t("config_page.speaker_device.label_auto_select")}

+ +
+
+

{t("config_page.mic_host_device.label_device")}

{ selectFunction={selectFunction} openListFunction={getSpeakerDeviceList} state={currentSelectedSpeakerDevice.state} + is_disabled={is_disabled_selector} />
diff --git a/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss b/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss index 1e2f9117..69928c70 100644 --- a/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/device/Device.module.scss @@ -57,13 +57,23 @@ gap: 2.8rem; } +.device_auto_select_wrapper { + display: flex; + flex-direction: column; + gap: 1.2rem; +} + .device_dropdown_wrapper { display: flex; flex-direction: column; gap: 0.6rem; + white-space: nowrap; + &.is_disabled { + pointer-events: none; + } } -.device_dropdown_label { +.device_secondary_label { padding-left: 0.2rem; font-size: 1.4rem; color: var(--dark_500_color); diff --git a/src-ui/logics/configs/useEnableAutoMicSelect.js b/src-ui/logics/configs/useEnableAutoMicSelect.js new file mode 100644 index 00000000..5dc5d8b1 --- /dev/null +++ b/src-ui/logics/configs/useEnableAutoMicSelect.js @@ -0,0 +1,28 @@ +import { useStore_EnableAutoMicSelect } from "@store"; +import { useStdoutToPython } from "@logics/useStdoutToPython"; + +export const useEnableAutoMicSelect = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + const { currentEnableAutoMicSelect, updateEnableAutoMicSelect } = useStore_EnableAutoMicSelect(); + + const getEnableAutoMicSelect = () => { + updateEnableAutoMicSelect(() => new Promise(() => {})); + asyncStdoutToPython("/config/enable_mic_automatic_selection"); + }; + + const toggleEnableAutoMicSelect = () => { + updateEnableAutoMicSelect(() => new Promise(() => {})); + if (currentEnableAutoMicSelect.data) { + asyncStdoutToPython("/controller/callback_disable_mic_automatic_selection"); + } else { + asyncStdoutToPython("/controller/callback_enable_mic_automatic_selection"); + } + }; + + return { + currentEnableAutoMicSelect, + getEnableAutoMicSelect, + updateEnableAutoMicSelect, + toggleEnableAutoMicSelect, + }; +}; \ No newline at end of file diff --git a/src-ui/logics/configs/useEnableAutoSpeakerSelect.js b/src-ui/logics/configs/useEnableAutoSpeakerSelect.js new file mode 100644 index 00000000..79895545 --- /dev/null +++ b/src-ui/logics/configs/useEnableAutoSpeakerSelect.js @@ -0,0 +1,28 @@ +import { useStore_EnableAutoSpeakerSelect } from "@store"; +import { useStdoutToPython } from "@logics/useStdoutToPython"; + +export const useEnableAutoSpeakerSelect = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + const { currentEnableAutoSpeakerSelect, updateEnableAutoSpeakerSelect } = useStore_EnableAutoSpeakerSelect(); + + const getEnableAutoSpeakerSelect = () => { + updateEnableAutoSpeakerSelect(() => new Promise(() => {})); + asyncStdoutToPython("/config/enable_speaker_automatic_selection"); + }; + + const toggleEnableAutoSpeakerSelect = () => { + updateEnableAutoSpeakerSelect(() => new Promise(() => {})); + if (currentEnableAutoSpeakerSelect.data) { + asyncStdoutToPython("/controller/callback_disable_speaker_automatic_selection"); + } else { + asyncStdoutToPython("/controller/callback_enable_speaker_automatic_selection"); + } + }; + + return { + currentEnableAutoSpeakerSelect, + getEnableAutoSpeakerSelect, + updateEnableAutoSpeakerSelect, + toggleEnableAutoSpeakerSelect, + }; +}; \ No newline at end of file diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index 6485513d..875b77a4 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -5,6 +5,8 @@ import { useSelectableLanguageList } from "./useSelectableLanguageList"; import { useVolume } from "./useVolume"; import { useSoftwareVersion } from "@logics_configs/useSoftwareVersion"; +import { useEnableAutoMicSelect } from "@logics_configs/useEnableAutoMicSelect"; +import { useEnableAutoSpeakerSelect } from "@logics_configs/useEnableAutoSpeakerSelect"; import { useMicHostList } from "@logics_configs/useMicHostList"; import { useSelectedMicHost } from "@logics_configs/useSelectedMicHost"; import { useMicDeviceList } from "@logics_configs/useMicDeviceList"; @@ -35,6 +37,10 @@ export const useReceiveRoutes = () => { } = useMessage(); const { updateSoftwareVersion } = useSoftwareVersion(); + + const { updateEnableAutoMicSelect } = useEnableAutoMicSelect(); + const { updateEnableAutoSpeakerSelect } = useEnableAutoSpeakerSelect(); + const { updateMicHostList } = useMicHostList(); const { updateSelectedMicHost } = useSelectedMicHost(); const { updateMicDeviceList } = useMicDeviceList(); @@ -70,6 +76,11 @@ export const useReceiveRoutes = () => { "/config/version": updateSoftwareVersion, + "/controller/callback_enable_mic_automatic_selection": updateEnableAutoMicSelect, + "/controller/callback_disable_mic_automatic_selection": updateEnableAutoMicSelect, + "/controller/callback_enable_speaker_automatic_selection": updateEnableAutoSpeakerSelect, + "/controller/callback_disable_speaker_automatic_selection": updateEnableAutoSpeakerSelect, + "/controller/list_mic_host": (payload) => updateMicHostList(arrayToObject(payload)), "/config/choice_mic_host": updateSelectedMicHost, "/controller/callback_set_mic_host": (payload) => { diff --git a/src-ui/store.js b/src-ui/store.js index b65e0395..907ef58b 100644 --- a/src-ui/store.js +++ b/src-ui/store.js @@ -117,6 +117,9 @@ export const { atomInstance: Atom_IsOpenedDropdownMenu, useHook: useStore_IsOpen // Config Page +export const { atomInstance: Atom_EnableAutoMicSelect, useHook: useStore_EnableAutoMicSelect } = createAsyncAtomWithHook(true, "EnableAutoMicSelect"); +export const { atomInstance: Atom_EnableAutoSpeakerSelect, useHook: useStore_EnableAutoSpeakerSelect } = createAsyncAtomWithHook(true, "EnableAutoSpeakerSelect"); + export const { atomInstance: Atom_MicHostList, useHook: useStore_MicHostList } = createAsyncAtomWithHook({}, "MicHostList"); export const { atomInstance: Atom_SelectedMicHost, useHook: useStore_SelectedMicHost } = createAsyncAtomWithHook("Nothing Selected", "SelectedMicHost"); export const { atomInstance: Atom_MicDeviceList, useHook: useStore_MicDeviceList } = createAsyncAtomWithHook({}, "MicDeviceList"); diff --git a/src-ui/utils/variables.css b/src-ui/utils/variables.css index 0f394542..1b462bf0 100644 --- a/src-ui/utils/variables.css +++ b/src-ui/utils/variables.css @@ -26,6 +26,7 @@ --dark_400_color: #c7c8cc; --dark_450_color: #b8b9bd; --dark_500_color: #a9aaae; + --dark_550_color: #949599; --dark_600_color: #7f8084; --dark_650_color: #75767a; --dark_700_color: #6a6c6f;