From ae38ed165df27ef5e43a09192532e494924edceb Mon Sep 17 00:00:00 2001
From: misyaguziya <53165965+misyaguziya@users.noreply.github.com>
Date: Fri, 30 May 2025 11:31:09 +0900
Subject: [PATCH 1/3] [Update] controller.py: Refactor OSC IP address handling
and improve VRC mic mute sync logic
---
src-python/controller.py | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/src-python/controller.py b/src-python/controller.py
index 821cd397..767fb21c 100644
--- a/src-python/controller.py
+++ b/src-python/controller.py
@@ -1137,8 +1137,7 @@ class Controller:
def getOscIpAddress(*args, **kwargs) -> dict:
return {"status":200, "result":config.OSC_IP_ADDRESS}
- @staticmethod
- def setOscIpAddress(data, *args, **kwargs) -> dict:
+ def setOscIpAddress(self, data, *args, **kwargs) -> dict:
if isValidIpAddress(data) is False:
response = {
"status":400,
@@ -1151,6 +1150,11 @@ class Controller:
try:
model.setOscIpAddress(data)
config.OSC_IP_ADDRESS = data
+ if model.getIsOscQueryEnabled() is True:
+ self.enableOscQuery()
+ else:
+ self.setDisableVrcMicMuteSync()
+ self.disableOscQuery()
response = {"status":200, "result":config.OSC_IP_ADDRESS}
except Exception:
model.setOscIpAddress(config.OSC_IP_ADDRESS)
@@ -1426,13 +1430,20 @@ class Controller:
@staticmethod
def setEnableVrcMicMuteSync(*args, **kwargs) -> dict:
- if model.getIsOscQueryEnabled() is False:
+ if model.getIsOscQueryEnabled() is True:
config.VRC_MIC_MUTE_SYNC = True
model.setMuteSelfStatus()
model.changeMicTranscriptStatus()
+ response = {"status":200, "result":config.VRC_MIC_MUTE_SYNC}
else:
- config.VRC_MIC_MUTE_SYNC = False
- return {"status":200, "result":config.VRC_MIC_MUTE_SYNC}
+ response = {
+ "status":400,
+ "result":{
+ "message":"Cannot enable VRC mic mute sync while OSC query is disabled",
+ "data": config.VRC_MIC_MUTE_SYNC
+ }
+ }
+ return response
@staticmethod
def setDisableVrcMicMuteSync(*args, **kwargs) -> dict:
@@ -1913,10 +1924,22 @@ class Controller:
self.run(200, self.run_mapping["initialization_progress"], progress)
def enableOscQuery(self):
- self.run(200, self.run_mapping["enable_osc_query"], True)
+ self.run(
+ 200,
+ self.run_mapping["enable_osc_query"],
+ {
+ "data": True,
+ "disabled_functions": []
+ }
+ )
def disableOscQuery(self):
- self.run(200, self.run_mapping["enable_osc_query"], False)
+ self.run(200, self.run_mapping["enable_osc_query"], {
+ "data": False,
+ "disabled_functions": [
+ "vrc_mic_mute_sync",
+ ]
+ })
def init(self, *args, **kwargs) -> None:
removeLog()
@@ -1999,6 +2022,8 @@ class Controller:
if osc_query_enabled is True:
self.enableOscQuery()
else:
+ # OSC Query is disabled, so disable VRC some features
+ config.VRC_MIC_MUTE_SYNC = False
self.disableOscQuery()
if config.VRC_MIC_MUTE_SYNC is True:
From 88cb4f72b53c71ca0c05d277532af00b7d2bec5f Mon Sep 17 00:00:00 2001
From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com>
Date: Fri, 30 May 2025 15:32:03 +0900
Subject: [PATCH 2/3] [Update/bugfix] UI: Add disable/enable UI function when
osc query is disabled. Fix the error that the mic mute sync couldn't
enable/disable.
---
locales/en.yml | 3 ++
locales/ja.yml | 3 ++
src-python/controller.py | 2 +-
src-ui/app/_index_css/variables.css | 1 +
.../setting_box/others/Others.jsx | 8 +++-
.../RightSideComponents.jsx | 2 +-
.../SnackbarController.jsx | 1 +
.../SnackbarController.module.scss | 3 ++
.../common_components/checkbox/Checkbox.jsx | 6 +--
.../checkbox/Checkbox.module.scss | 9 +++-
src-ui/logics/common/index.js | 1 +
src-ui/logics/common/useHandleOscQuery.js | 44 +++++++++++++++++++
src-ui/logics/common/useNotificationStatus.js | 11 +++++
.../configs/others/useEnableVrcMicMuteSync.js | 2 +-
src-ui/logics/useReceiveRoutes.js | 20 +++++++--
src-ui/store.js | 13 +++++-
16 files changed, 116 insertions(+), 13 deletions(-)
create mode 100644 src-ui/logics/common/useHandleOscQuery.js
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)
From 149c3b10933b51bd2fde2abe6596c556f7dcb552 Mon Sep 17 00:00:00 2001
From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com>
Date: Fri, 30 May 2025 16:36:29 +0900
Subject: [PATCH 3/3] =?UTF-8?q?[bugfix]=20UI:=20OSC=E3=82=AF=E3=82=A8?=
=?UTF-8?q?=E3=83=AA=E7=84=A1=E5=8A=B9=E6=99=82=E3=80=81=E3=83=9F=E3=83=A5?=
=?UTF-8?q?=E3=83=BC=E3=83=88=E5=90=8C=E6=9C=9F=E6=A9=9F=E8=83=BD=E3=81=8C?=
=?UTF-8?q?=E7=84=A1=E5=8A=B9=E3=81=AB=E3=81=AA=E3=82=89=E3=81=AA=E3=81=84?=
=?UTF-8?q?=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src-ui/logics/common/useHandleOscQuery.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src-ui/logics/common/useHandleOscQuery.js b/src-ui/logics/common/useHandleOscQuery.js
index 357df7fd..2e6b1681 100644
--- a/src-ui/logics/common/useHandleOscQuery.js
+++ b/src-ui/logics/common/useHandleOscQuery.js
@@ -18,7 +18,7 @@ export const useHandleOscQuery = () => {
for (const disabled_function of disabled_functions) {
if (disabled_function === "vrc_mic_mute_sync") {
updateEnableVrcMicMuteSync({
- is_enabled: !is_osc_query_enabled,
+ is_enabled: false,
is_available: false,
});
const item = `- ${t("config_page.others.vrc_mic_mute_sync.label")}`;