diff --git a/locales/en.yml b/locales/en.yml index d7a2347a..5138f697 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -24,6 +24,9 @@ common_error: invalid_value_speaker_phrase_timeout: "It cannot be set lower than '{{speaker_record_timeout_label}}' with a value of 0 or more." invalid_value_speaker_max_phrase: "You can set a number equal to or greater than 0." +common_warning: + unable_to_use_osc_query: "The functions below have been automatically disabled because receiving OSC data is not possible due to OSC IP Address settings." + main_page: translation: "Translation" transcription_send: "Voice2Chatbox" diff --git a/locales/ja.yml b/locales/ja.yml index 7286cb54..b8d70695 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -24,6 +24,9 @@ common_error: invalid_value_speaker_phrase_timeout: "0 以上で 「{{speaker_record_timeout_label}}」 より小さくすることはできません。" invalid_value_speaker_max_phrase: "0 以上の数値を設定できます。" +common_warning: + unable_to_use_osc_query: "OSC IP Address の設定によりOSCデータの受信ができないため、以下の機能が自動的に無効になっています。" + main_page: translation: "翻訳" transcription_send: "音声認識 マイク" diff --git a/src-python/controller.py b/src-python/controller.py index 767fb21c..080df101 100644 --- a/src-python/controller.py +++ b/src-python/controller.py @@ -1443,7 +1443,7 @@ class Controller: "data": config.VRC_MIC_MUTE_SYNC } } - return response + return response @staticmethod def setDisableVrcMicMuteSync(*args, **kwargs) -> dict: diff --git a/src-ui/app/_index_css/variables.css b/src-ui/app/_index_css/variables.css index 6a3c48e4..ca2beca1 100644 --- a/src-ui/app/_index_css/variables.css +++ b/src-ui/app/_index_css/variables.css @@ -25,6 +25,7 @@ --error_bc_active_color: #9c3938; --success_bc_color: #368777; --waring_color: #cb944f; + --waring_bc_color: #cf7b1b; --dark_basic_text_color: #f2f2f2; --dark_100_color: #f5f7fb; diff --git a/src-ui/app/config_page/setting_section/setting_box/others/Others.jsx b/src-ui/app/config_page/setting_section/setting_box/others/Others.jsx index d8d7b818..b6c9c9b6 100644 --- a/src-ui/app/config_page/setting_section/setting_box/others/Others.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/others/Others.jsx @@ -101,11 +101,17 @@ export const VrcMicMuteSyncContainer = () => { const { t } = useTranslation(); const { currentEnableVrcMicMuteSync, toggleEnableVrcMicMuteSync } = useEnableVrcMicMuteSync(); + const variable = { + state: currentEnableVrcMicMuteSync.state, + data: currentEnableVrcMicMuteSync.data.is_enabled, + }; + return ( ); diff --git a/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx b/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx index 7bd3ae59..3f8be6e2 100644 --- a/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx +++ b/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx @@ -77,7 +77,7 @@ const OpenVrcMicMuteSyncQuickSetting = () => { return ( ); diff --git a/src-ui/app/snackbar_controller/SnackbarController.jsx b/src-ui/app/snackbar_controller/SnackbarController.jsx index 0b7c9609..e503e695 100644 --- a/src-ui/app/snackbar_controller/SnackbarController.jsx +++ b/src-ui/app/snackbar_controller/SnackbarController.jsx @@ -14,6 +14,7 @@ export const SnackbarController = () => { const snackbar_classname = clsx(styles.snackbar_content, { [styles.is_success]: currentNotificationStatus.data.status === "success", + [styles.is_warning]: currentNotificationStatus.data.status === "warning", [styles.is_error]: currentNotificationStatus.data.status === "error", }); diff --git a/src-ui/app/snackbar_controller/SnackbarController.module.scss b/src-ui/app/snackbar_controller/SnackbarController.module.scss index b0b96ce9..075e4419 100644 --- a/src-ui/app/snackbar_controller/SnackbarController.module.scss +++ b/src-ui/app/snackbar_controller/SnackbarController.module.scss @@ -6,6 +6,9 @@ &.is_success { background-color: var(--success_bc_color); } + &.is_warning { + background-color: var(--waring_bc_color); + } &.is_error { background-color: var(--error_bc_color); } diff --git a/src-ui/common_components/checkbox/Checkbox.jsx b/src-ui/common_components/checkbox/Checkbox.jsx index 50ee51a9..64904243 100644 --- a/src-ui/common_components/checkbox/Checkbox.jsx +++ b/src-ui/common_components/checkbox/Checkbox.jsx @@ -3,15 +3,16 @@ import styles from "./Checkbox.module.scss"; export const Checkbox = ({ checkboxId, variable, + is_available = true, toggleFunction, size = "2.8rem", - color = "var(--primary_600_color)", borderWidth = "0.2rem", padding = "2rem", }) => { const wrapper_class_names = clsx(styles.checkbox_wrapper, { - [styles.is_disabled]: variable.state === "pending", + [styles.is_disabled]: !is_available, + [styles.is_pending]: variable.state === "pending", }); return ( @@ -21,7 +22,6 @@ export const Checkbox = ({ htmlFor={checkboxId} style={{ "--checkbox-size": size, - "--checkbox-color": color, "--checkbox-border-width": borderWidth, "--checkbox-padding": padding, }} diff --git a/src-ui/common_components/checkbox/Checkbox.module.scss b/src-ui/common_components/checkbox/Checkbox.module.scss index 70f47654..090fed2b 100644 --- a/src-ui/common_components/checkbox/Checkbox.module.scss +++ b/src-ui/common_components/checkbox/Checkbox.module.scss @@ -18,12 +18,19 @@ border: var(--checkbox-color, var(--primary_600_color)) solid var(--checkbox-border-width, 0.2rem); } } - &.is_disabled { + &.is_pending { pointer-events: none; & .cbx { border-color: var(--primary_800_color); } } + &.is_disabled { + pointer-events: none; + & .cbx { + filter: grayscale(100%); + border-color: var(--dark_800_color); + } + } } .checkbox_wrapper .cbx { diff --git a/src-ui/logics/common/index.js b/src-ui/logics/common/index.js index e95bae8f..c03d13eb 100644 --- a/src-ui/logics/common/index.js +++ b/src-ui/logics/common/index.js @@ -11,5 +11,6 @@ export { useMessage } from "./useMessage"; export { useUpdateSoftware } from "./useUpdateSoftware"; export { useVolume } from "./useVolume"; export { useHandleNetworkConnection } from "./useHandleNetworkConnection"; +export { useHandleOscQuery } from "./useHandleOscQuery"; export { useIsVrctAvailable } from "./useIsVrctAvailable"; export { useFetch } from "./useFetch"; \ No newline at end of file diff --git a/src-ui/logics/common/useHandleOscQuery.js b/src-ui/logics/common/useHandleOscQuery.js new file mode 100644 index 00000000..357df7fd --- /dev/null +++ b/src-ui/logics/common/useHandleOscQuery.js @@ -0,0 +1,44 @@ +import { useTranslation } from "react-i18next"; +import { useNotificationStatus } from "@logics_common"; +import { + useEnableVrcMicMuteSync, +} from "@logics_configs"; + +export const useHandleOscQuery = () => { + const { t } = useTranslation(); + + const { showNotification_Warning } = useNotificationStatus(); + const { updateEnableVrcMicMuteSync } = useEnableVrcMicMuteSync(); + + const handleOscQuery = ({is_osc_query_enabled, disabled_functions}) => { + if (!is_osc_query_enabled && disabled_functions.length > 0) { + const BASE_LABEL = t("common_warning.unable_to_use_osc_query"); + let items_label = ""; + + for (const disabled_function of disabled_functions) { + if (disabled_function === "vrc_mic_mute_sync") { + updateEnableVrcMicMuteSync({ + is_enabled: !is_osc_query_enabled, + is_available: false, + }); + const item = `- ${t("config_page.others.vrc_mic_mute_sync.label")}`; + items_label = `${items_label}\n${item}`; + } + } + const label = `${BASE_LABEL}${items_label}`; + showNotification_Warning( + label, + { hide_duration: 10000, } + ); + } else if (is_osc_query_enabled) { + updateEnableVrcMicMuteSync((old_value) => ({ + ...old_value.data, + is_available: true, + })); + } + }; + + return { + handleOscQuery, + }; +}; \ No newline at end of file diff --git a/src-ui/logics/common/useNotificationStatus.js b/src-ui/logics/common/useNotificationStatus.js index a5b7bc3c..f4aab3ed 100644 --- a/src-ui/logics/common/useNotificationStatus.js +++ b/src-ui/logics/common/useNotificationStatus.js @@ -5,6 +5,16 @@ export const useNotificationStatus = () => { const generateRandomKey = () => Math.random(); + const showNotification_Warning = (message, options = {}) => { + updateNotificationStatus({ + status: "warning", + is_open: true, + key: generateRandomKey(), + message: message, + options: options, + }); + }; + const showNotification_Error = (message, options = {}) => { updateNotificationStatus({ status: "error", @@ -37,6 +47,7 @@ export const useNotificationStatus = () => { currentNotificationStatus, updateNotificationStatus, + showNotification_Warning, showNotification_Error, showNotification_Success, closeNotification, diff --git a/src-ui/logics/configs/others/useEnableVrcMicMuteSync.js b/src-ui/logics/configs/others/useEnableVrcMicMuteSync.js index 16a853ab..6515ffc2 100644 --- a/src-ui/logics/configs/others/useEnableVrcMicMuteSync.js +++ b/src-ui/logics/configs/others/useEnableVrcMicMuteSync.js @@ -12,7 +12,7 @@ export const useEnableVrcMicMuteSync = () => { const toggleEnableVrcMicMuteSync = () => { pendingEnableVrcMicMuteSync(); - if (currentEnableVrcMicMuteSync.data) { + if (currentEnableVrcMicMuteSync.data.is_enabled) { asyncStdoutToPython("/set/disable/vrc_mic_mute_sync"); } else { asyncStdoutToPython("/set/enable/vrc_mic_mute_sync"); diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index 3cde999a..b1d3421b 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -7,6 +7,7 @@ import { useIsVrctAvailable, useNotificationStatus, useHandleNetworkConnection, + useHandleOscQuery, useSoftwareVersion, useComputeMode, @@ -83,6 +84,7 @@ export const useReceiveRoutes = () => { const { updateComputeMode } = useComputeMode(); const { updateInitProgress } = useInitProgress(); const { updateIsBackendReady } = useIsBackendReady(); + const { handleOscQuery } = useHandleOscQuery(); const { restoreWindowGeometry } = useWindow(); const { updateIsMainPageCompactMode } = useIsMainPageCompactMode(); const { @@ -219,6 +221,12 @@ export const useReceiveRoutes = () => { })); }, "/run/connected_network": handleNetworkConnection, + "/run/enable_osc_query": ({data, disabled_functions}) => { + handleOscQuery({ + is_osc_query_enabled: data, + disabled_functions: disabled_functions, + }); + }, // Main Page // Page Controls @@ -480,9 +488,15 @@ export const useReceiveRoutes = () => { "/set/enable/logger_feature": updateEnableAutoExportMessageLogs, "/set/disable/logger_feature": updateEnableAutoExportMessageLogs, - "/get/data/vrc_mic_mute_sync": updateEnableVrcMicMuteSync, - "/set/enable/vrc_mic_mute_sync": updateEnableVrcMicMuteSync, - "/set/disable/vrc_mic_mute_sync": updateEnableVrcMicMuteSync, + "/get/data/vrc_mic_mute_sync": (payload) => updateEnableVrcMicMuteSync((old_value) => { + return {...old_value.data, is_enabled: payload}; + }), + "/set/enable/vrc_mic_mute_sync": (payload) => updateEnableVrcMicMuteSync((old_value) => { + return {...old_value.data, is_enabled: payload}; + }), + "/set/disable/vrc_mic_mute_sync": (payload) => updateEnableVrcMicMuteSync((old_value) => { + return {...old_value.data, is_enabled: payload}; + }), "/get/data/send_message_to_vrc": updateEnableSendMessageToVrc, "/set/enable/send_message_to_vrc": updateEnableSendMessageToVrc, diff --git a/src-ui/store.js b/src-ui/store.js index f33ebbfc..06fc859a 100644 --- a/src-ui/store.js +++ b/src-ui/store.js @@ -60,10 +60,19 @@ export const createAtomWithHook = (initialValue, base_name, options) => { }; const updateAtom = (payload, options = {}) => { - const { remain_state = false, set_state } = options; + const { remain_state = false, set_state, lock_state } = options; setAtom((currentValue) => { - const new_state = set_state ?? (remain_state ? currentValue.state : "ok"); + let new_state; + if (lock_state) { + new_state = set_state; + } else { + if (currentValue.lock_state) { + new_state = currentValue.state; + } else { + new_state = set_state ?? (remain_state ? currentValue.state : "ok"); + } + } const updated_data = typeof payload === "function" ? payload(currentValue)