Merge branch 'bugfix_ui' into develop

This commit is contained in:
Sakamoto Shiina
2025-06-23 13:16:14 +09:00
8 changed files with 82 additions and 31 deletions

View File

@@ -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.

View File

@@ -282,6 +282,7 @@ plugin_notifications:
updated_error: プラグインのアップデートに失敗しました。
disabled_out_of_support: 現在のバージョンとの互換性がありません。プラグインを無効にしました。
disabled_due_to_an_error: プラグイン実行中にエラーを検知しました。プラグイン開発者に報告してください。
is_enabled: プラグインを有効にしました。
is_disabled: プラグインを無効にしました。

View File

@@ -105,7 +105,12 @@ const PluginDownloadContainer = () => {
</div>
<div className={styles.plugin_info_wrapper}>
{plugin.is_error ? (
<p style={{ color: "red" }}>Error: {plugin.error_message}</p>
<div>
<p style={{ color: "red" }}>{t(`plugin_notifications.${plugin.error_message_type}`)}</p>
<p style={{ color: "red" }}>plugin_version: {plugin.downloaded_plugin_info.plugin_version}</p>
<p style={{ color: "red" }}>min_supported_vrct_version: {plugin.downloaded_plugin_info.min_supported_vrct_version}</p>
<p style={{ color: "red" }}>max_supported_vrct_version: {plugin.downloaded_plugin_info.max_supported_vrct_version}</p>
</div>
) : (
<PluginsControlComponent
variable_state={variable_state}

View File

@@ -27,6 +27,7 @@
flex-direction: column;
gap: 0.4rem;
max-width: 50%;
flex-shrink: 0;
}
.plugin_info_wrapper {

View File

@@ -1,14 +1,28 @@
import React from "react";
import { usePlugins } from "@logics_configs";
import { ErrorBoundary } from "react-error-boundary";
export const PluginHost = ({render_components}) => {
export const PluginHost = ({ render_components }) => {
const { setErrorPlugin } = usePlugins();
return (
<>
{render_components
.map((plugin, index) => {
const PluginComponent = plugin.component;
return PluginComponent ? <PluginComponent key={index} /> : null;
})}
{render_components.map((plugin, index) => {
const PluginComponent = plugin.component;
const plugin_id = plugin.plugin_id;
return PluginComponent ? (
<ErrorBoundary
key={plugin_id || index}
fallbackRender={() => null}
onError={(_error, _info) => {
// Disable the plugin on error
setErrorPlugin(plugin_id, "disabled_due_to_an_error");
}}
>
<PluginComponent />
</ErrorBoundary>
) : null;
})}
</>
);
};

View File

@@ -69,14 +69,14 @@ export const SnackbarController = () => {
}, 100);
};
setContainerKey(prevKey => prevKey + 1);
// setContainerKey(prevKey => prevKey + 1);
asyncShowNotification();
}, [settings]);
return (
<ToastContainer
key={containerKey}
// key={containerKey}
position="bottom-left"
transition={CustomTransition}
hideProgressBar={false}

View File

@@ -282,44 +282,57 @@ export const usePlugins = () => {
});
};
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,
};
};

View File

@@ -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" },