From 418d9f4ad701b5226bc2c34b0ed9ddb960a64794 Mon Sep 17 00:00:00 2001
From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com>
Date: Sun, 15 Sep 2024 23:22:10 +0900
Subject: [PATCH] [Update] Config Page: Device Tab. Add mic/speaker auto select
section.
---
locales/en.json | 5 ++-
.../components/dropdown_menu/DropdownMenu.jsx | 8 ++--
.../dropdown_menu/DropdownMenu.module.scss | 12 ++++++
.../setting_box/device/Device.jsx | 37 +++++++++++++++++--
.../setting_box/device/Device.module.scss | 12 +++++-
.../logics/configs/useEnableAutoMicSelect.js | 28 ++++++++++++++
.../configs/useEnableAutoSpeakerSelect.js | 28 ++++++++++++++
src-ui/logics/useReceiveRoutes.js | 11 ++++++
src-ui/store.js | 3 ++
src-ui/utils/variables.css | 1 +
10 files changed, 137 insertions(+), 8 deletions(-)
create mode 100644 src-ui/logics/configs/useEnableAutoMicSelect.js
create mode 100644 src-ui/logics/configs/useEnableAutoSpeakerSelect.js
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;