From b15a26c3d56aae0dfeed342a7ba5ecf5e22ff905 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Mon, 23 Jun 2025 11:24:18 +0900 Subject: [PATCH 1/2] [bugfix] Plugins: Add error handling. when error occurred while rendering a plugin, set status disabled and an error. --- locales/en.yml | 3 +- locales/ja.yml | 1 + .../setting_box/plugins/Plugins.jsx | 7 +- .../setting_box/plugins/Plugins.module.scss | 1 + .../app/main_page/main_section/PluginHost.jsx | 28 ++++++-- .../SnackbarController.jsx | 4 +- src-ui/logics/configs/plugins/usePlugins.js | 64 +++++++++++++------ 7 files changed, 78 insertions(+), 30 deletions(-) diff --git a/locales/en.yml b/locales/en.yml index 9e133bed..05e5601d 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -270,7 +270,7 @@ config_page: label: "WebSocket Port" notifications: - save_success: "Settings have been saved" + save_success: "Settings have been saved." plugin_notifications: downloading: Downloading the plugin. @@ -282,6 +282,7 @@ plugin_notifications: updated_error: Update failed. disabled_out_of_support: The plugin has been disabled. It's not supported on this VRCT version. + disabled_due_to_an_error: "An error was detected while running the plugin. Please report this to the plugin developer." is_enabled: The plugin has enabled. is_disabled: The plugin has disabled. \ No newline at end of file diff --git a/locales/ja.yml b/locales/ja.yml index b2ff2ad8..d36bec89 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -282,6 +282,7 @@ plugin_notifications: updated_error: プラグインのアップデートに失敗しました。 disabled_out_of_support: 現在のバージョンとの互換性がありません。プラグインを無効にしました。 + disabled_due_to_an_error: プラグイン実行中にエラーを検知しました。プラグイン開発者に報告してください。 is_enabled: プラグインを有効にしました。 is_disabled: プラグインを無効にしました。 \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/plugins/Plugins.jsx b/src-ui/app/config_page/setting_section/setting_box/plugins/Plugins.jsx index aa4cdf75..6c80beb2 100644 --- a/src-ui/app/config_page/setting_section/setting_box/plugins/Plugins.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/plugins/Plugins.jsx @@ -105,7 +105,12 @@ const PluginDownloadContainer = () => {
{plugin.is_error ? ( -

Error: {plugin.error_message}

+
+

{t(`plugin_notifications.${plugin.error_message_type}`)}

+

plugin_version: {plugin.downloaded_plugin_info.plugin_version}

+

min_supported_vrct_version: {plugin.downloaded_plugin_info.min_supported_vrct_version}

+

max_supported_vrct_version: {plugin.downloaded_plugin_info.max_supported_vrct_version}

+
) : ( { +export const PluginHost = ({ render_components }) => { + const { setErrorPlugin } = usePlugins(); return ( <> - {render_components - .map((plugin, index) => { - const PluginComponent = plugin.component; - return PluginComponent ? : null; - })} + {render_components.map((plugin, index) => { + const PluginComponent = plugin.component; + const plugin_id = plugin.plugin_id; + + return PluginComponent ? ( + null} + onError={(_error, _info) => { + // Disable the plugin on error + setErrorPlugin(plugin_id, "disabled_due_to_an_error"); + }} + > + + + ) : null; + })} ); }; \ No newline at end of file diff --git a/src-ui/app/others/snackbar_controller/SnackbarController.jsx b/src-ui/app/others/snackbar_controller/SnackbarController.jsx index fe692c10..60edac1f 100644 --- a/src-ui/app/others/snackbar_controller/SnackbarController.jsx +++ b/src-ui/app/others/snackbar_controller/SnackbarController.jsx @@ -69,14 +69,14 @@ export const SnackbarController = () => { }, 100); }; - setContainerKey(prevKey => prevKey + 1); + // setContainerKey(prevKey => prevKey + 1); asyncShowNotification(); }, [settings]); return ( { }); }; - const toggleSavedPluginsStatus = (target_plugin_id) => { - const successPluginNotification = (message) => showNotification_Success(message, { - hide_duration: 1000, - category_id: "to_enable_plugin" - }); - const is_exists = currentSavedPluginsStatus.data.some( + const setSavedPluginEnabled = (target_plugin_id, is_enabled) => { + const notify = () => { + const msg_key = is_enabled + ? "plugin_notifications.is_enabled" + : "plugin_notifications.is_disabled"; + showNotification_Success(t(msg_key), { + hide_duration: 1000, + category_id: "switch_enable_plugin", + }); + } + + const exists = currentSavedPluginsStatus.data.some( (d) => d.plugin_id === target_plugin_id ); + let new_value = []; - if (is_exists) { + + if (exists) { new_value = currentSavedPluginsStatus.data.map((d) => { if (d.plugin_id === target_plugin_id) { - d.is_enabled = !d.is_enabled; - (d.is_enabled) - ? successPluginNotification(t("plugin_notifications.is_enabled")) - : successPluginNotification(t("plugin_notifications.is_disabled")); + d.is_enabled = is_enabled; + notify(); } return d; }); } else { - new_value.push(...currentSavedPluginsStatus.data); - new_value.push({ - plugin_id: target_plugin_id, - is_enabled: true, - }); - successPluginNotification(t("plugin_notifications.is_enabled")) + // 存在しない場合は追加 + new_value = [ + ...currentSavedPluginsStatus.data, + { plugin_id: target_plugin_id, is_enabled: is_enabled } + ]; + notify(); } - // 「currentPluginsData.data」でis_downloadedがtrueのものだけ残す + // ダウンロード済みプラグインのみ残す new_value = new_value.filter((item) => currentPluginsData.data.some( - (plugin) => plugin.plugin_id === item.plugin_id && plugin.is_downloaded + (p) => p.plugin_id === item.plugin_id && p.is_downloaded ) ); setSavedPluginsStatus(new_value); }; + const toggleSavedPluginsStatus = (plugin_id) => { + // 現在の状態を探す(未登録なら false とみなす) + const current = currentSavedPluginsStatus.data.find( + (d) => d.plugin_id === plugin_id + )?.is_enabled ?? false; + setSavedPluginEnabled(plugin_id, !current); + }; // Init時の処理 非対応のものを無効化する際に、savedDPluginsStatusから不要なものを削除する処理が邪魔になるので該当コードを削除したバージョン。Init以外で使用する時にはリファクタが必要になる。 const setTargetSavedPluginsStatus_Init = (target_plugin_id, is_enabled) => { @@ -380,6 +393,15 @@ export const usePlugins = () => { showNotification_SaveSuccess(); }; + const setErrorPlugin = (plugin_id, error_message_type) => { + const error_message = t("plugin_notifications.disabled_due_to_an_error"); + + setSavedPluginEnabled(plugin_id, false); + updateTargetPluginData(plugin_id, "is_error", true); + updateTargetPluginData(plugin_id, "error_message_type", error_message_type); + showNotification_Error(error_message); + }; + return { asyncFetchPluginsInfo, @@ -406,11 +428,15 @@ export const usePlugins = () => { currentLoadedPlugins, updateLoadedPlugins, + setSavedPluginEnabled, toggleSavedPluginsStatus, setTargetSavedPluginsStatus_Init, setSavedPluginsStatus, + handlePendingPlugin, + + setErrorPlugin, }; }; From 49366791fbc3a87ef2064aa7f249a7501c681f0a Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Mon, 23 Jun 2025 12:47:43 +0900 Subject: [PATCH 2/2] [bugfix/Chore] Fix update function.(Notification was not shown even the software update has available.) Add noop endpoints '/run/update_software' and '/run/update_cuda_software'. --- src-ui/logics/useReceiveRoutes.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index 5c0e78e1..d83054d3 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -10,6 +10,9 @@ export const ROUTE_META_LIST = [ { endpoint: "/run/enable_ai_models", ns: common, hook_name: "useIsVrctAvailable", method_name: "handleAiModelsAvailability" }, { endpoint: "/get/data/compute_mode", ns: common, hook_name: "useComputeMode", method_name: "updateComputeMode" }, + { endpoint: "/run/update_software", ns: null, hook_name: null, method_name: null }, + { endpoint: "/run/update_cuda_software", ns: null, hook_name: null, method_name: null }, + { endpoint: "/get/data/main_window_geometry", ns: common, hook_name: "useWindow", method_name: "restoreWindowGeometry" }, { endpoint: "/set/data/main_window_geometry", ns: null, hook_name: null, method_name: null }, @@ -19,7 +22,7 @@ export const ROUTE_META_LIST = [ // Software Version { endpoint: "/get/data/version", ns: common, hook_name: "useSoftwareVersion", method_name: "updateSoftwareVersion" }, // Latest Software Version Info - { endpoint: "/run/software_update_info", ns: common, hook_name: "useSoftwareVersion", method_name: "updateLatestSoftwareVersionInfo" }, + { endpoint: "/run/software_update_info", ns: common, hook_name: "useSoftwareVersion", method_name: "updateSoftwareVersionInfo" }, { endpoint: "/run/connected_network", ns: common, hook_name: "useHandleNetworkConnection", method_name: "handleNetworkConnection" }, { endpoint: "/run/enable_osc_query", ns: common, hook_name: "useHandleOscQuery", method_name: "handleOscQuery" },