diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx
index 8c33ed37..f8314681 100644
--- a/src-ui/app/App.jsx
+++ b/src-ui/app/App.jsx
@@ -29,7 +29,10 @@ export const App = () => {
const { currentIsBackendReady } = useIsBackendReady();
const { WindowGeometryController } = useWindow();
const { i18n } = useTranslation();
- const fetchPluginsHasRunRef = useRef(false);
+ const fetchPluginsHasRunRef = useRef({
+ is_initialized_load_plugin: false,
+ is_fetched_plugins_info: false,
+ });
return (
diff --git a/src-ui/app/_app_controllers/PluginsController.jsx b/src-ui/app/_app_controllers/PluginsController.jsx
index 98327baf..9939bfe3 100644
--- a/src-ui/app/_app_controllers/PluginsController.jsx
+++ b/src-ui/app/_app_controllers/PluginsController.jsx
@@ -1,142 +1,15 @@
-import React, { useEffect, useRef } from "react";
-import { usePlugins } from "@logics_configs";
-import clsx from "clsx";
+import React, { useEffect } from "react";
+import { LoadPluginsController } from "./plugins_controllers/LoadPluginsController";
+import { FetchLatestPluginsDataController } from "./plugins_controllers/FetchLatestPluginsDataController";
+import { MergeSavedPluginsStatusController } from "./plugins_controllers/MergeSavedPluginsStatusController";
-if (typeof window !== "undefined") {
- window.React = React;
- window.clsx = clsx;
-}
+export const PluginsController = () => {
-export const PluginsController = ({ fetchPluginsHasRunRef }) => {
- const {
- asyncLoadAllPlugins,
- asyncFetchPluginsInfo,
- currentPluginsData,
- updatePluginsData,
- currentSavedPluginsStatus,
- updateIsPluginsInitialized,
- downloadAndExtractPlugin,
- } = usePlugins();
-
- useEffect(() => {
- const loadPlugins = async () => {
- try {
- await asyncLoadAllPlugins();
- const info_array = await asyncFetchPluginsInfo();
- updatePluginsData(prev => {
- // Map を利用してそれぞれの配列を plugin_id で参照できるようにする
- const info_map = new Map(info_array.map(info => [info.plugin_id, info]));
- const prev_map = new Map(prev.data.map(item => [item.plugin_id, item]));
-
- const new_data = [];
- for (const info of info_array) {
- let new_plugin_info = {};
- if (prev_map.has(info.plugin_id)) { // plugin_id 登録済み
- const target_downloaded_plugin = prev_map.get(info.plugin_id);
- if (target_downloaded_plugin.is_downloaded) { // 既にダウンロード済み
- const is_latest_version_available = !(target_downloaded_plugin.plugin_version === info.plugin_version);
-
- new_plugin_info = {
- ...target_downloaded_plugin,
- is_downloaded: true,
- latest_plugin_info: { ...info },
- is_latest_version_available: is_latest_version_available,
- is_latest_version_already: (target_downloaded_plugin.downloaded_plugin_info?.plugin_version === info.plugin_version),
- };
- } else { // infoにもあり登録済みだがダウンロードされていない
- new_plugin_info = {
- ...target_downloaded_plugin,
- is_downloaded: false,
- is_latest_version_already: false,
- is_latest_version_available: info.is_latest_version_available,
- latest_plugin_info: { ...info },
- }
- }
- } else { // 未ダウンロード
- new_plugin_info = {
- plugin_id: info.plugin_id,
- is_downloaded: false,
- is_latest_version_already: false,
- latest_plugin_info: { ...info },
- };
- }
- new_data.push(new_plugin_info);
- }
-
- // prev.data にのみ存在するアイテム = latest plugin infoには存在しない
- // を追加し、is_outdated: true を付与
- prev.data.forEach(item => {
- if (!info_map.has(item.plugin_id)) {
- new_data.push({ ...item, is_outdated: true });
- }
- });
-
- new_data.forEach(plugin => {
- if (!plugin.is_outdated) {
- plugin.is_latest_version_available = (plugin.latest_plugin_info.is_plugin_supported);
- }
- });
-
- // ダウンロード済みで最新版じゃない場合、自動的にアップデート
- // is_latest_version_supported: true のみ。
- // 失敗した場合、現在のバージョンが非対応の場合はdisabledにする。
- new_data.forEach(async plugin => {
- if (plugin.is_enabled) {
- if (!plugin.is_latest_version_already && plugin.is_latest_version_available) {
- await downloadAndExtractPlugin(plugin);
- }
- }
- });
-
- new_data.forEach(async plugin => {
- if (plugin.is_enabled) {
- if (!plugin.downloaded_plugin_info?.is_plugin_supported) {
- plugin.is_enabled = false
- }
- }
- });
-
- return new_data;
- });
-
- } catch (error) {
- console.error(error);
- }
- };
-
- if (!fetchPluginsHasRunRef.current) {
- loadPlugins();
- updateIsPluginsInitialized(true);
- }
- return () => fetchPluginsHasRunRef.current = true;
- }, []);
-
-
- useEffect(() => {
- updatePluginsData(prev => {
- // currentSavedPluginsStatus.data の各要素を Map 化して plugin_id で参照
- const saved_map = new Map(currentSavedPluginsStatus.data.map(saved => [saved.plugin_id, saved]));
- const prev_map = new Map(prev.data.map(item => [item.plugin_id, item]));
- // prev.data にある各アイテムについて、保存済みの状態情報があればマージ
- const merged = prev.data.map(item => {
-
- if (saved_map.has(item.plugin_id)) {
- return { ...item, is_enabled: saved_map.get(item.plugin_id).is_enabled };
- }
- return item;
- });
-
- // currentSavedPluginsStatus.data にのみ存在する項目があれば追加
- currentSavedPluginsStatus.data.forEach(saved => {
- if (!prev_map.has(saved.plugin_id)) {
- merged.push({ plugin_id: saved.plugin_id, is_enabled: saved.is_enabled });
- }
- });
- return merged;
- });
- }, [currentSavedPluginsStatus]);
-
-
-
- return null;
+ return (
+ <>
+
+
+
+ >
+ );
};
\ No newline at end of file
diff --git a/src-ui/app/_app_controllers/plugins_controllers/FetchLatestPluginsDataController.jsx b/src-ui/app/_app_controllers/plugins_controllers/FetchLatestPluginsDataController.jsx
new file mode 100644
index 00000000..e0fde914
--- /dev/null
+++ b/src-ui/app/_app_controllers/plugins_controllers/FetchLatestPluginsDataController.jsx
@@ -0,0 +1,115 @@
+import { useEffect } from "react";
+import { usePlugins } from "@logics_configs";
+
+export const FetchLatestPluginsDataController = () => {
+ const {
+ asyncFetchPluginsInfo,
+ updatePluginsData,
+ downloadAndExtractPlugin,
+ currentIsInitializedLoadPlugin,
+ currentIsFetchedPluginsInfo,
+ updateIsFetchedPluginsInfo,
+ } = usePlugins();
+
+ const asyncUpdateLatestPluginsData = async () => {
+ try {
+ const info_array = await asyncFetchPluginsInfo();
+ updatePluginsData(prev => {
+ // Map を利用してそれぞれの配列を plugin_id で参照できるようにする
+ const info_map = new Map(info_array.map(info => [info.plugin_id, info]));
+ const prev_map = new Map(prev.data.map(item => [item.plugin_id, item]));
+
+ console.log(prev_map);
+
+ const new_data = [];
+ for (const info of info_array) {
+ let new_plugin_info = {};
+ if (prev_map.has(info.plugin_id)) { // plugin_id 登録済み
+ const target_downloaded_plugin = prev_map.get(info.plugin_id);
+
+ if (target_downloaded_plugin.is_downloaded) { // 既にダウンロード済み
+ const is_latest_version_available = !(target_downloaded_plugin.plugin_version === info.plugin_version);
+
+ new_plugin_info = {
+ ...target_downloaded_plugin,
+ is_downloaded: true,
+ latest_plugin_info: { ...info },
+ is_latest_version_available: is_latest_version_available,
+ is_latest_version_already: (target_downloaded_plugin.downloaded_plugin_info?.plugin_version === info.plugin_version),
+ };
+ } else { // infoにもあり登録済みだがダウンロードされていない
+ new_plugin_info = {
+ ...target_downloaded_plugin,
+ is_downloaded: false,
+ is_latest_version_already: false,
+ is_latest_version_available: info.is_latest_version_available,
+ latest_plugin_info: { ...info },
+ }
+ }
+ } else { // 未ダウンロード
+ new_plugin_info = {
+ plugin_id: info.plugin_id,
+ is_downloaded: false,
+ is_latest_version_already: false,
+ latest_plugin_info: { ...info },
+ };
+ }
+
+ new_data.push(new_plugin_info);
+ }
+
+ // prev.data にのみ存在するアイテム = latest plugin infoには存在しない
+ // を追加し、is_outdated: true を付与
+ prev.data.forEach(item => {
+ if (!info_map.has(item.plugin_id)) {
+ new_data.push({ ...item, is_outdated: true });
+ }
+ });
+
+ new_data.forEach(plugin => {
+ if (!plugin.is_outdated) {
+ plugin.is_latest_version_available = (plugin.latest_plugin_info.is_plugin_supported);
+ }
+ });
+
+ // ダウンロード済みで最新版じゃない場合、自動的にアップデート
+ // is_latest_version_supported: true のみ。
+ // 失敗した場合、現在のバージョンが非対応の場合はdisabledにする。
+ new_data.forEach(async plugin => {
+ if (plugin.is_enabled) {
+ console.log(plugin);
+
+ if (!plugin.is_latest_version_already && plugin.is_latest_version_available) {
+ await downloadAndExtractPlugin(plugin);
+ }
+ }
+ });
+
+ new_data.forEach(async plugin => {
+ if (plugin.is_downloaded && plugin.is_enabled) {
+ if (!plugin.downloaded_plugin_info?.is_plugin_supported && !plugin.latest_plugin_info?.is_plugin_supported) {
+ plugin.is_enabled = false
+ }
+ }
+ });
+
+ return new_data;
+ });
+
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ useEffect(() => {
+ console.log(currentIsInitializedLoadPlugin.data);
+ if (currentIsInitializedLoadPlugin.data && !currentIsFetchedPluginsInfo.data) {
+ asyncUpdateLatestPluginsData().then(() => {
+ updateIsFetchedPluginsInfo(true);
+ });
+ }
+
+ }, [currentIsInitializedLoadPlugin.data]);
+
+ return null;
+};
\ No newline at end of file
diff --git a/src-ui/app/_app_controllers/plugins_controllers/LoadPluginsController.jsx b/src-ui/app/_app_controllers/plugins_controllers/LoadPluginsController.jsx
new file mode 100644
index 00000000..23422cc5
--- /dev/null
+++ b/src-ui/app/_app_controllers/plugins_controllers/LoadPluginsController.jsx
@@ -0,0 +1,36 @@
+import React, { useEffect } from "react";
+import { usePlugins } from "@logics_configs";
+import clsx from "clsx";
+
+if (typeof window !== "undefined") {
+ window.React = React;
+ window.clsx = clsx;
+}
+
+export const LoadPluginsController = () => {
+
+ const {
+ asyncLoadAllPlugins,
+ currentIsInitializedLoadPlugin,
+ updateIsInitializedLoadPlugin,
+ } = usePlugins();
+
+ const asyncInitLoadPlugins = async () => {
+ try {
+ await asyncLoadAllPlugins();
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ useEffect(() => {
+
+ if (!currentIsInitializedLoadPlugin.data) {
+ asyncInitLoadPlugins().then(() => {
+ updateIsInitializedLoadPlugin(true);
+ });
+ }
+ }, []);
+
+ return null;
+};
\ No newline at end of file
diff --git a/src-ui/app/_app_controllers/plugins_controllers/MergeSavedPluginsStatusController.jsx b/src-ui/app/_app_controllers/plugins_controllers/MergeSavedPluginsStatusController.jsx
new file mode 100644
index 00000000..9b3dcb23
--- /dev/null
+++ b/src-ui/app/_app_controllers/plugins_controllers/MergeSavedPluginsStatusController.jsx
@@ -0,0 +1,35 @@
+import { useEffect } from "react";
+import { usePlugins } from "@logics_configs";
+
+export const MergeSavedPluginsStatusController = () => {
+ const {
+ updatePluginsData,
+ currentSavedPluginsStatus,
+ } = usePlugins();
+
+ useEffect(() => {
+ updatePluginsData(prev => {
+ // currentSavedPluginsStatus.data の各要素を Map 化して plugin_id で参照
+ const saved_map = new Map(currentSavedPluginsStatus.data.map(saved => [saved.plugin_id, saved]));
+ const prev_map = new Map(prev.data.map(item => [item.plugin_id, item]));
+ // prev.data にある各アイテムについて、保存済みの状態情報があればマージ
+ const merged = prev.data.map(item => {
+
+ if (saved_map.has(item.plugin_id)) {
+ return { ...item, is_enabled: saved_map.get(item.plugin_id).is_enabled };
+ }
+ return item;
+ });
+
+ // currentSavedPluginsStatus.data にのみ存在する項目があれば追加
+ currentSavedPluginsStatus.data.forEach(saved => {
+ if (!prev_map.has(saved.plugin_id)) {
+ merged.push({ plugin_id: saved.plugin_id, is_enabled: saved.is_enabled });
+ }
+ });
+ return merged;
+ });
+ }, [currentSavedPluginsStatus]);
+
+ return null;
+};
\ No newline at end of file
diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/plugins_control_component/PluginsControlComponent.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/plugins_control_component/PluginsControlComponent.jsx
index e6ddd500..9c33c90d 100644
--- a/src-ui/app/config_page/setting_section/setting_box/_components/plugins_control_component/PluginsControlComponent.jsx
+++ b/src-ui/app/config_page/setting_section/setting_box/_components/plugins_control_component/PluginsControlComponent.jsx
@@ -54,11 +54,27 @@ const DownloadedPluginControl = ({
if (!plugin_status.downloaded_plugin_info.is_plugin_supported) {
+ if (plugin_status.is_latest_version_available) {
+ return (
+
+
最新のバージョン: {latest_version}
+
最新版にアップデート後 利用可能
+ <_DownloadButton option={option} downloadStartFunction={downloadStartFunction} />
+
+ );
+ }
return (
現在利用不可 使用中VRCTバージョンとの互換性なし
);
+ } else if (plugin_status.is_outdated) {
+ return (
+
+ );
} else if (plugin_status.is_latest_version_already) {
return (
diff --git a/src-ui/app/modal_controller/update_modal/UpdateModal.jsx b/src-ui/app/modal_controller/update_modal/UpdateModal.jsx
index 4fef1c71..caf89d43 100644
--- a/src-ui/app/modal_controller/update_modal/UpdateModal.jsx
+++ b/src-ui/app/modal_controller/update_modal/UpdateModal.jsx
@@ -20,9 +20,6 @@ export const UpdateModal = () => {
const { currentLatestSoftwareVersionInfo } = useSoftwareVersion();
const { isAnyPluginEnabled } = usePlugins();
- console.log(isAnyPluginEnabled());
-
-
const is_latest_version_already = currentLatestSoftwareVersionInfo.data.is_update_available === false;
const is_cpu_version = currentComputeMode.data === "cpu";
@@ -101,14 +98,17 @@ const CurrentVersionLabel = (props) => {
const PluginUpdateNotification = () => {
const { enabledPluginsList } = usePlugins();
- const incompatible_plugins_list = enabledPluginsList();
+ // ダウンロード済みのもの or プラグイン最新版が、VRCT最新版(VRCTアプデ後)に非対応のもの
+ const incompatible_plugins_list = enabledPluginsList().filter(plugin => {
+ if (!plugin.is_downloaded) return false;
+ if (!plugin.downloaded_plugin_info?.is_plugin_supported_latest_vrct || !plugin.latest_plugin_info.is_plugin_supported_latest_vrct) return true;
+ });
return (
{incompatible_plugins_list.map(plugin => {
- console.log(plugin);
-
- return
{plugin.title}
+ const target_data = plugin.downloaded_plugin_info;
+ return
{target_data.title}
})}
);
diff --git a/src-ui/logics/configs/plugins/usePlugins.js b/src-ui/logics/configs/plugins/usePlugins.js
index 9f1be315..aa8c5ad7 100644
--- a/src-ui/logics/configs/plugins/usePlugins.js
+++ b/src-ui/logics/configs/plugins/usePlugins.js
@@ -5,6 +5,8 @@ import {
useStore_SavedPluginsStatus,
useStore_PluginsData,
useStore_IsPluginsInitialized,
+ useStore_IsInitializedLoadPlugin,
+ useStore_IsFetchedPluginsInfo,
} from "@store";
import { useStdoutToPython } from "@logics/useStdoutToPython";
@@ -33,6 +35,11 @@ const PLUGIN_LIST_URL = getPluginsList();
export const usePlugins = () => {
const { asyncStdoutToPython } = useStdoutToPython();
+
+ const { currentIsInitializedLoadPlugin, updateIsInitializedLoadPlugin, pendingIsInitializedLoadPlugin } = useStore_IsInitializedLoadPlugin();
+ const { currentIsFetchedPluginsInfo, updateIsFetchedPluginsInfo, pendingIsFetchedPluginsInfo } = useStore_IsFetchedPluginsInfo();
+
+
const { currentSavedPluginsStatus, updateSavedPluginsStatus, pendingSavedPluginsStatus } = useStore_SavedPluginsStatus();
const { currentPluginsData, updatePluginsData, pendingPluginsData } = useStore_PluginsData();
const { currentIsPluginsInitialized, updateIsPluginsInitialized, pendingIsPluginsInitialized } = useStore_IsPluginsInitialized();
@@ -40,13 +47,15 @@ export const usePlugins = () => {
const { asyncTauriFetchGithub } = useFetch();
- const generatePluginContext= (downloaded_plugin_info) => {
+ const generatePluginContext = (downloaded_plugin_info) => {
const plugin_context = {
registerComponent: (component) => {
if (!downloaded_plugin_info.plugin_id || !downloaded_plugin_info.location || !component) {
return console.error("An invalid plugin was detected.", downloaded_plugin_info.plugin_id, downloaded_plugin_info.location, component);
}
updatePluginsData(prev => {
+ console.log("-----updated downloaded plugin info----");
+
const prev_map = new Map(prev.data.map(item => [item.plugin_id, item]));
const new_data = [];
let new_value = {};
@@ -74,7 +83,7 @@ export const usePlugins = () => {
if (old_plugin_data.plugin_id === downloaded_plugin_info.plugin_id) { // ダウンロード済み or 登録済 アップデート
const target_prev_plugin = prev_map.get(downloaded_plugin_info.plugin_id);
- const is_latest_version_available = (target_prev_plugin.is_downloaded) && !(downloaded_plugin_info.plugin_version === target_prev_plugin.latest_plugin_info.plugin_version);
+ const is_latest_version_available = (target_prev_plugin.is_downloaded) && (target_prev_plugin.latest_plugin_info?.plugin_version) && !(downloaded_plugin_info.plugin_version === target_prev_plugin.latest_plugin_info?.plugin_version);
new_value = {
...target_prev_plugin,
@@ -357,6 +366,11 @@ export const usePlugins = () => {
currentIsPluginsInitialized,
updateIsPluginsInitialized,
+ currentIsInitializedLoadPlugin,
+ updateIsInitializedLoadPlugin,
+ currentIsFetchedPluginsInfo,
+ updateIsFetchedPluginsInfo,
+
setSavedPluginsStatus,
handlePendingPlugin,
diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js
index b73fe62e..fb826f8c 100644
--- a/src-ui/logics/useReceiveRoutes.js
+++ b/src-ui/logics/useReceiveRoutes.js
@@ -206,7 +206,13 @@ export const useReceiveRoutes = () => {
"/set/data/main_window_geometry": () => {},
"/run/open_filepath_logs": () => console.log("Opened Directory, Message Logs"),
"/run/open_filepath_config_file": () => console.log("Opened Directory, Config File"),
- "/run/software_update_info": updateLatestSoftwareVersionInfo,
+ "/run/software_update_info": () => {
+ updateLatestSoftwareVersionInfo({
+ is_update_available: true,
+ new_version: "3.0.3",
+ })
+ },
+ // "/run/software_update_info": updateLatestSoftwareVersionInfo,
"/run/connected_network": handleNetworkConnection,
// Main Page
diff --git a/src-ui/store.js b/src-ui/store.js
index 5adbb4c7..58012777 100644
--- a/src-ui/store.js
+++ b/src-ui/store.js
@@ -279,6 +279,9 @@ export const { atomInstance: Atom_Hotkeys, useHook: useStore_Hotkeys } = createA
// Plugins
export const { atomInstance: Atom_IsPluginsInitialized, useHook: useStore_IsPluginsInitialized } = createAtomWithHook(false, "IsPluginsInitialized");
+export const { atomInstance: Atom_IsInitializedLoadPlugin, useHook: useStore_IsInitializedLoadPlugin } = createAtomWithHook(false, "IsInitializedLoadPlugin");
+export const { atomInstance: Atom_IsFetchedPluginsInfo, useHook: useStore_IsFetchedPluginsInfo } = createAtomWithHook(false, "IsFetchedPluginsInfo");
+export const { atomInstance: Atom_FetchedPluginsInfo, useHook: useStore_FetchedPluginsInfo } = createAtomWithHook(false, "FetchedPluginsInfo");
export const { atomInstance: Atom_SavedPluginsStatus, useHook: useStore_SavedPluginsStatus } = createAtomWithHook([], "SavedPluginsStatus");
export const { atomInstance: Atom_PluginsData, useHook: useStore_PluginsData } = createAtomWithHook([], "PluginsData");