[Update] (Affect to backend) Plugin System. Saveable if the plugin is enabled or not.
Add functions that merge plugins data.
This commit is contained in:
@@ -555,6 +555,18 @@ class Config:
|
|||||||
self._HOTKEYS[key] = value
|
self._HOTKEYS[key] = value
|
||||||
self.saveConfig(inspect.currentframe().f_code.co_name, self.HOTKEYS, immediate_save=True)
|
self.saveConfig(inspect.currentframe().f_code.co_name, self.HOTKEYS, immediate_save=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@json_serializable('PLUGINS_STATUS')
|
||||||
|
def PLUGINS_STATUS(self):
|
||||||
|
return self._PLUGINS_STATUS
|
||||||
|
|
||||||
|
@PLUGINS_STATUS.setter
|
||||||
|
def PLUGINS_STATUS(self, value):
|
||||||
|
if isinstance(value, list):
|
||||||
|
if all(isinstance(item, dict) for item in value):
|
||||||
|
self._PLUGINS_STATUS = value
|
||||||
|
self.saveConfig(inspect.currentframe().f_code.co_name, self.PLUGINS_STATUS, immediate_save=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@json_serializable('MIC_AVG_LOGPROB')
|
@json_serializable('MIC_AVG_LOGPROB')
|
||||||
def MIC_AVG_LOGPROB(self):
|
def MIC_AVG_LOGPROB(self):
|
||||||
@@ -1068,6 +1080,7 @@ class Config:
|
|||||||
"toggle_transcription_send": None,
|
"toggle_transcription_send": None,
|
||||||
"toggle_transcription_receive": None,
|
"toggle_transcription_receive": None,
|
||||||
}
|
}
|
||||||
|
self._PLUGINS_STATUS = []
|
||||||
self._MIC_AVG_LOGPROB = -0.8
|
self._MIC_AVG_LOGPROB = -0.8
|
||||||
self._MIC_NO_SPEECH_PROB = 0.6
|
self._MIC_NO_SPEECH_PROB = 0.6
|
||||||
self._AUTO_SPEAKER_SELECT = True
|
self._AUTO_SPEAKER_SELECT = True
|
||||||
|
|||||||
@@ -1061,6 +1061,15 @@ class Controller:
|
|||||||
config.HOTKEYS = data
|
config.HOTKEYS = data
|
||||||
return {"status":200, "result":config.HOTKEYS}
|
return {"status":200, "result":config.HOTKEYS}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getPluginsStatus(*args, **kwargs) -> dict:
|
||||||
|
return {"status":200, "result":config.PLUGINS_STATUS}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setPluginsStatus(data, *args, **kwargs) -> dict:
|
||||||
|
config.PLUGINS_STATUS = data
|
||||||
|
return {"status":200, "result":config.PLUGINS_STATUS}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getSpeakerAvgLogprob(*args, **kwargs) -> dict:
|
def getSpeakerAvgLogprob(*args, **kwargs) -> dict:
|
||||||
return {"status":200, "result":config.SPEAKER_AVG_LOGPROB}
|
return {"status":200, "result":config.SPEAKER_AVG_LOGPROB}
|
||||||
|
|||||||
@@ -190,6 +190,9 @@ mapping = {
|
|||||||
"/get/data/hotkeys": {"status": True, "variable":controller.getHotkeys},
|
"/get/data/hotkeys": {"status": True, "variable":controller.getHotkeys},
|
||||||
"/set/data/hotkeys": {"status": True, "variable":controller.setHotkeys},
|
"/set/data/hotkeys": {"status": True, "variable":controller.setHotkeys},
|
||||||
|
|
||||||
|
"/get/data/plugins_status": {"status": True, "variable":controller.getPluginsStatus},
|
||||||
|
"/set/data/plugins_status": {"status": True, "variable":controller.setPluginsStatus},
|
||||||
|
|
||||||
"/get/data/mic_avg_logprob": {"status": True, "variable":controller.getMicAvgLogprob},
|
"/get/data/mic_avg_logprob": {"status": True, "variable":controller.getMicAvgLogprob},
|
||||||
"/set/data/mic_avg_logprob": {"status": True, "variable":controller.setMicAvgLogprob},
|
"/set/data/mic_avg_logprob": {"status": True, "variable":controller.setMicAvgLogprob},
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useRef } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -29,6 +30,7 @@ export const App = () => {
|
|||||||
const { currentIsBackendReady } = useIsBackendReady();
|
const { currentIsBackendReady } = useIsBackendReady();
|
||||||
const { WindowGeometryController } = useWindow();
|
const { WindowGeometryController } = useWindow();
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
|
const fetchPluginsHasRunRef = useRef(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
@@ -44,7 +46,7 @@ export const App = () => {
|
|||||||
|
|
||||||
{(currentIsBackendReady.data === false || currentIsVrctAvailable.data === false)
|
{(currentIsBackendReady.data === false || currentIsVrctAvailable.data === false)
|
||||||
? <SplashComponent />
|
? <SplashComponent />
|
||||||
: <Contents key={i18n.language}/>
|
: <Contents key={i18n.language} fetchPluginsHasRunRef={fetchPluginsHasRunRef} />
|
||||||
}
|
}
|
||||||
|
|
||||||
<SnackbarController />
|
<SnackbarController />
|
||||||
@@ -52,11 +54,11 @@ export const App = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Contents = () => {
|
const Contents = ({ fetchPluginsHasRunRef }) => {
|
||||||
const { currentIsSoftwareUpdating } = useIsSoftwareUpdating();
|
const { currentIsSoftwareUpdating } = useIsSoftwareUpdating();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PluginsController />
|
<PluginsController fetchPluginsHasRunRef={fetchPluginsHasRunRef} />
|
||||||
<SubtitlesController />
|
<SubtitlesController />
|
||||||
|
|
||||||
<WindowTitleBar />
|
<WindowTitleBar />
|
||||||
|
|||||||
@@ -5,21 +5,80 @@ if (typeof window !== "undefined") {
|
|||||||
window.React = React;
|
window.React = React;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PluginsController = () => {
|
export const PluginsController = ({ fetchPluginsHasRunRef }) => {
|
||||||
const hasRunRef = useRef(false);
|
|
||||||
const {
|
const {
|
||||||
loadAllPlugins,
|
asyncLoadAllPlugins,
|
||||||
asyncUpdatePluginInfoList,
|
asyncFetchPluginsInfo,
|
||||||
|
currentPluginsData,
|
||||||
|
updatePluginsData,
|
||||||
|
currentSavedPluginsStatus,
|
||||||
} = usePlugins();
|
} = usePlugins();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hasRunRef.current) {
|
const loadPlugins = async () => {
|
||||||
asyncUpdatePluginInfoList().then(() => {
|
try {
|
||||||
loadAllPlugins();
|
await asyncLoadAllPlugins();
|
||||||
});
|
const info_array = await asyncFetchPluginsInfo();
|
||||||
|
updatePluginsData(prev => {
|
||||||
|
// Map を利用してそれぞれの配列を plugin_id で参照できるようにする
|
||||||
|
const infoMap = new Map(info_array.map(info => [info.plugin_id, info]));
|
||||||
|
const prevMap = new Map(prev.data.map(item => [item.plugin_id, item]));
|
||||||
|
|
||||||
|
// info_array にある各アイテムについて、prev.data に同じ plugin_id があればマージ
|
||||||
|
const merged = info_array.map(info => {
|
||||||
|
if (prevMap.has(info.plugin_id)) {
|
||||||
|
return { ...info, ...prevMap.get(info.plugin_id) };
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
});
|
||||||
|
|
||||||
|
// prev.data にのみ存在するアイテムを追加し、is_outdated: true を付与
|
||||||
|
prev.data.forEach(item => {
|
||||||
|
if (!infoMap.has(item.plugin_id)) {
|
||||||
|
merged.push({ ...item, is_outdated: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!fetchPluginsHasRunRef.current) {
|
||||||
|
loadPlugins();
|
||||||
}
|
}
|
||||||
return () => hasRunRef.current = true;
|
return () => fetchPluginsHasRunRef.current = true;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updatePluginsData(prev => {
|
||||||
|
// currentSavedPluginsStatus.data の各要素を Map 化して plugin_id で参照
|
||||||
|
const savedMap = new Map(currentSavedPluginsStatus.data.map(saved => [saved.plugin_id, saved]));
|
||||||
|
const prevMap = new Map(prev.data.map(item => [item.plugin_id, item]));
|
||||||
|
|
||||||
|
// prev.data にある各アイテムについて、保存済みの状態情報があればマージ
|
||||||
|
const merged = prev.data.map(item => {
|
||||||
|
if (savedMap.has(item.plugin_id)) {
|
||||||
|
return { ...item, is_enabled: savedMap.get(item.plugin_id).is_enabled };
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
// currentSavedPluginsStatus.data にのみ存在する項目があれば追加
|
||||||
|
currentSavedPluginsStatus.data.forEach(saved => {
|
||||||
|
if (!prevMap.has(saved.plugin_id)) {
|
||||||
|
merged.push({ plugin_id: saved.plugin_id, is_enabled: saved.is_enabled });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
});
|
||||||
|
}, [currentSavedPluginsStatus]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import {
|
|
||||||
SwitchBox,
|
|
||||||
} from "../index";
|
|
||||||
import { _DownloadButton } from "../_atoms/_download_button/_DownloadButton";
|
|
||||||
import styles from "./DownloadPlugins.module.scss";
|
|
||||||
|
|
||||||
export const DownloadPlugins = ({plugin_info, plugin_status, ...props}) => {
|
|
||||||
const option = {
|
|
||||||
id: plugin_info.plugin_id,
|
|
||||||
is_pending: plugin_info.is_pending,
|
|
||||||
is_downloaded: plugin_info.is_downloaded,
|
|
||||||
progress: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.container}>
|
|
||||||
{plugin_info.is_downloaded && plugin_info.is_plugin_supported &&
|
|
||||||
<SwitchBox
|
|
||||||
variable={plugin_status}
|
|
||||||
toggleFunction={plugin_status.toggleFunction}
|
|
||||||
/>}
|
|
||||||
{plugin_info.is_plugin_supported ?
|
|
||||||
<_DownloadButton
|
|
||||||
option={option}
|
|
||||||
downloadStartFunction={props.downloadStartFunction}
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<div className={styles.unavailable_text}>
|
|
||||||
Downloaded but outdated.
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -12,4 +12,4 @@ export { SwitchBox } from "./switch_box/SwitchBox";
|
|||||||
export { ThresholdComponent } from "./threshold_component/ThresholdComponent";
|
export { ThresholdComponent } from "./threshold_component/ThresholdComponent";
|
||||||
export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter";
|
export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter";
|
||||||
export { DownloadModels } from "./download_models/DownloadModels";
|
export { DownloadModels } from "./download_models/DownloadModels";
|
||||||
export { DownloadPlugins } from "./download_plugins/DownloadPlugins";
|
export { PluginsControlComponent } from "./plugins_control_component/PluginsControlComponent";
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import {
|
||||||
|
SwitchBox,
|
||||||
|
} from "../index";
|
||||||
|
import { _DownloadButton } from "../_atoms/_download_button/_DownloadButton";
|
||||||
|
import styles from "./PluginsControlComponent.module.scss";
|
||||||
|
|
||||||
|
export const PluginsControlComponent = ({ variable_state, plugin_status, toggleFunction, ...props }) => {
|
||||||
|
const option = {
|
||||||
|
id: plugin_status.plugin_id,
|
||||||
|
is_pending: plugin_status.is_pending,
|
||||||
|
is_downloaded: plugin_status.is_downloaded,
|
||||||
|
data: plugin_status.is_enabled,
|
||||||
|
state: variable_state,
|
||||||
|
progress: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const adjustedToggleFunction = () => {
|
||||||
|
toggleFunction(plugin_status.plugin_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_turn_on_able = false;
|
||||||
|
if (plugin_status.is_downloaded && plugin_status.is_plugin_supported) {
|
||||||
|
is_turn_on_able = true;
|
||||||
|
}
|
||||||
|
if (plugin_status.is_outdated) {
|
||||||
|
is_turn_on_able = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
{is_turn_on_able &&
|
||||||
|
<SwitchBox
|
||||||
|
variable={option}
|
||||||
|
toggleFunction={adjustedToggleFunction}
|
||||||
|
/>}
|
||||||
|
{plugin_status.is_plugin_supported ?
|
||||||
|
<_DownloadButton
|
||||||
|
option={option}
|
||||||
|
downloadStartFunction={props.downloadStartFunction}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<div className={styles.unavailable_text}>
|
||||||
|
Downloaded but outdated.
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.toggle_control {
|
.toggle_control {
|
||||||
|
position: relative;
|
||||||
@include toggle_control_styles;
|
@include toggle_control_styles;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { usePlugins } from "@logics_configs";
|
import { usePlugins } from "@logics_configs";
|
||||||
import styles from "./Plugins.module.scss";
|
import styles from "./Plugins.module.scss";
|
||||||
import { DownloadPlugins } from "../_components";
|
import { PluginsControlComponent } from "../_components";
|
||||||
|
|
||||||
export const Plugins = () => {
|
export const Plugins = () => {
|
||||||
return (
|
return (
|
||||||
@@ -14,16 +14,15 @@ export const Plugins = () => {
|
|||||||
const PluginDownloadContainer = () => {
|
const PluginDownloadContainer = () => {
|
||||||
const {
|
const {
|
||||||
downloadAndExtractPlugin,
|
downloadAndExtractPlugin,
|
||||||
currentPluginsInfoList,
|
currentPluginsData,
|
||||||
updatePluginsInfoList,
|
updatePluginsData,
|
||||||
currentSavedPluginsStatus,
|
currentSavedPluginsStatus,
|
||||||
updateSavedPluginsStatus,
|
setSavedPluginsStatus,
|
||||||
currentLoadedPluginsList,
|
|
||||||
// updateLoadedPluginsList,
|
|
||||||
} = usePlugins();
|
} = usePlugins();
|
||||||
|
|
||||||
|
|
||||||
const downloadStartFunction = async (target_plugin_id) => {
|
const downloadStartFunction = async (target_plugin_id) => {
|
||||||
updatePluginsInfoList((old_value) => {
|
updatePluginsData((old_value) => {
|
||||||
const new_value = old_value.data.map(d => {
|
const new_value = old_value.data.map(d => {
|
||||||
if (d.plugin_id === target_plugin_id) {
|
if (d.plugin_id === target_plugin_id) {
|
||||||
d.is_pending = true;
|
d.is_pending = true;
|
||||||
@@ -32,9 +31,9 @@ const PluginDownloadContainer = () => {
|
|||||||
});
|
});
|
||||||
return new_value;
|
return new_value;
|
||||||
});
|
});
|
||||||
const target_plugin_info = currentPluginsInfoList.data.find(d => d.plugin_id === target_plugin_id);
|
const target_plugin_info = currentPluginsData.data.find(d => d.plugin_id === target_plugin_id);
|
||||||
downloadAndExtractPlugin(target_plugin_info).then(() => {
|
downloadAndExtractPlugin(target_plugin_info).then(() => {
|
||||||
updatePluginsInfoList((old_value) => {
|
updatePluginsData((old_value) => {
|
||||||
const new_value = old_value.data.map(d => {
|
const new_value = old_value.data.map(d => {
|
||||||
if (d.plugin_id === target_plugin_id) {
|
if (d.plugin_id === target_plugin_id) {
|
||||||
d.is_pending = false;
|
d.is_pending = false;
|
||||||
@@ -46,60 +45,41 @@ const PluginDownloadContainer = () => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
// console.log(currentPluginsInfoList.data);
|
|
||||||
|
|
||||||
|
|
||||||
// const plugin_list = currentPluginsInfoList.data;
|
const toggleFunction = (target_plugin_id) => {
|
||||||
const plugin_list = [...currentPluginsInfoList.data, ...currentLoadedPluginsList.data];
|
const is_exists = currentSavedPluginsStatus.data.some(d => d.plugin_id === target_plugin_id);
|
||||||
// const plugin_list = [
|
let new_value = [];
|
||||||
// {
|
if (is_exists) {
|
||||||
// title: "VRCT Example Plugins 1",
|
new_value = currentSavedPluginsStatus.data.map(d => {
|
||||||
// plugin_id: "vrct_plugin_example_1",
|
if (d.plugin_id === target_plugin_id) {
|
||||||
// asset_name: "vrct_plugin_example_1.zip",
|
d.is_enabled = !d.is_enabled;
|
||||||
// plugin_version: "0.0.6",
|
}
|
||||||
// min_supported_vrct_version: "3.0.4",
|
return d;
|
||||||
// max_supported_vrct_version: "3.0.6",
|
});
|
||||||
// is_plugin_supported: true,
|
} else {
|
||||||
// // url: manifest_url
|
new_value.push(...currentSavedPluginsStatus.data);
|
||||||
// },
|
new_value.push({
|
||||||
// {
|
plugin_id: target_plugin_id,
|
||||||
// title: "VRCT Example Plugins 2",
|
is_enabled: true,
|
||||||
// plugin_id: "vrct_plugin_example_2",
|
|
||||||
// asset_name: "vrct_plugin_example_2.zip",
|
|
||||||
// plugin_version: "0.0.1",
|
|
||||||
// min_supported_vrct_version: "3.0.4",
|
|
||||||
// max_supported_vrct_version: "3.0.7",
|
|
||||||
// is_plugin_supported: true,
|
|
||||||
// // url: manifest_url
|
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
|
|
||||||
const getTargetPluginStatus = (target_plugin_id) => {
|
|
||||||
let plugin_status = currentSavedPluginsStatus.data.find(d => d.plugin_id === target_plugin_id) ?? {};
|
|
||||||
const is_downloaded = currentLoadedPluginsList.data.find(d => d.plugin_id === target_plugin_id) ? true : false;
|
|
||||||
|
|
||||||
plugin_status.toggleFunction = () => {
|
|
||||||
updateSavedPluginsStatus((old_value) => {
|
|
||||||
const new_value = old_value.data.map(d => {
|
|
||||||
if (d.plugin_id === target_plugin_id) {
|
|
||||||
d.data = !d.data;
|
|
||||||
d.state = "ok";
|
|
||||||
}
|
|
||||||
return d;
|
|
||||||
});
|
|
||||||
return new_value;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
plugin_status.is_downloaded = is_downloaded;
|
|
||||||
plugin_status.is_pending = false;
|
|
||||||
return plugin_status;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
// currentPluginsData.data で、is_downloaded が true のものだけ残す
|
||||||
|
new_value = new_value.filter(item => {
|
||||||
|
return currentPluginsData.data.some(plugin => plugin.plugin_id === item.plugin_id && plugin.is_downloaded);
|
||||||
|
});
|
||||||
|
|
||||||
|
setSavedPluginsStatus(new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const variable_state = currentSavedPluginsStatus.state;
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.plugins_list_container}>
|
<div className={styles.plugins_list_container}>
|
||||||
{plugin_list.map((plugin) => (
|
{currentPluginsData.data.map((plugin) => (
|
||||||
<div key={plugin.plugin_id} className={styles.plugin_wrapper}>
|
<div key={plugin.plugin_id} className={styles.plugin_wrapper}>
|
||||||
<p className={styles.title}>{plugin.title}</p>
|
<p className={styles.title}>{plugin.title}</p>
|
||||||
<p className={styles.plugin_id}>{plugin.plugin_id}</p>
|
<p className={styles.plugin_id}>{plugin.plugin_id}</p>
|
||||||
@@ -113,9 +93,10 @@ const PluginDownloadContainer = () => {
|
|||||||
Compatible: {plugin.min_supported_vrct_version} ~ {plugin.max_supported_vrct_version}
|
Compatible: {plugin.min_supported_vrct_version} ~ {plugin.max_supported_vrct_version}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<DownloadPlugins
|
<PluginsControlComponent
|
||||||
plugin_info={plugin}
|
variable_state={variable_state}
|
||||||
plugin_status={getTargetPluginStatus(plugin.plugin_id)}
|
toggleFunction={toggleFunction}
|
||||||
|
plugin_status={plugin}
|
||||||
downloadStartFunction={downloadStartFunction}
|
downloadStartFunction={downloadStartFunction}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,13 +2,12 @@ import React from "react";
|
|||||||
import { usePlugins } from "@logics_configs";
|
import { usePlugins } from "@logics_configs";
|
||||||
|
|
||||||
export const PluginHost = () => {
|
export const PluginHost = () => {
|
||||||
const { currentLoadedPluginsList } = usePlugins();
|
const { currentPluginsData } = usePlugins();
|
||||||
// console.log(currentLoadedPluginsList.data);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{currentLoadedPluginsList.data
|
{currentPluginsData.data
|
||||||
.filter((plugin) => plugin.location === "main_section")
|
.filter((plugin) => plugin.is_enabled && plugin.location === "main_section")
|
||||||
.map((plugin, index) => {
|
.map((plugin, index) => {
|
||||||
const PluginComponent = plugin.component;
|
const PluginComponent = plugin.component;
|
||||||
return PluginComponent ? <PluginComponent key={index} /> : null;
|
return PluginComponent ? <PluginComponent key={index} /> : null;
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import semver from "semver";
|
|||||||
import { invoke } from "@tauri-apps/api/tauri";
|
import { invoke } from "@tauri-apps/api/tauri";
|
||||||
import {
|
import {
|
||||||
createAtomWithHook,
|
createAtomWithHook,
|
||||||
useStore_LoadedPluginsList,
|
|
||||||
useStore_SavedPluginsStatus,
|
useStore_SavedPluginsStatus,
|
||||||
useStore_PluginsInfoList,
|
useStore_PluginsData,
|
||||||
} from "@store";
|
} from "@store";
|
||||||
|
import { useStdoutToPython } from "@logics/useStdoutToPython";
|
||||||
|
|
||||||
import { transform } from "@babel/standalone";
|
import { transform } from "@babel/standalone";
|
||||||
import { writeFile, createDir, exists, removeDir, readDir, BaseDirectory, readTextFile } from "@tauri-apps/api/fs";
|
import { writeFile, createDir, exists, removeDir, readDir, BaseDirectory, readTextFile } from "@tauri-apps/api/fs";
|
||||||
@@ -21,9 +21,10 @@ import { useSoftwareVersion } from "@logics_configs";
|
|||||||
const PLUGIN_LIST_URL = "https://raw.githubusercontent.com/ShiinaSakamoto/vrct_plugins_list/main/vrct_plugins_list.json";
|
const PLUGIN_LIST_URL = "https://raw.githubusercontent.com/ShiinaSakamoto/vrct_plugins_list/main/vrct_plugins_list.json";
|
||||||
|
|
||||||
export const usePlugins = () => {
|
export const usePlugins = () => {
|
||||||
const { currentLoadedPluginsList, updateLoadedPluginsList } = useStore_LoadedPluginsList();
|
const { asyncStdoutToPython } = useStdoutToPython();
|
||||||
const { currentSavedPluginsStatus, updateSavedPluginsStatus } = useStore_SavedPluginsStatus();
|
// const { currentLoadedPluginsList, updateLoadedPluginsList } = useStore_LoadedPluginsList();
|
||||||
const { currentPluginsInfoList, updatePluginsInfoList, pendingPluginsInfoList } = useStore_PluginsInfoList();
|
const { currentSavedPluginsStatus, updateSavedPluginsStatus, pendingSavedPluginsStatus } = useStore_SavedPluginsStatus();
|
||||||
|
const { currentPluginsData, updatePluginsData, pendingPluginsData } = useStore_PluginsData();
|
||||||
const { currentSoftwareVersion } = useSoftwareVersion();
|
const { currentSoftwareVersion } = useSoftwareVersion();
|
||||||
|
|
||||||
const { asyncTauriFetchGithub } = useFetch();
|
const { asyncTauriFetchGithub } = useFetch();
|
||||||
@@ -33,9 +34,17 @@ export const usePlugins = () => {
|
|||||||
if (!plugin_id || !location || !component) {
|
if (!plugin_id || !location || !component) {
|
||||||
return console.error("An invalid plugin was detected.", plugin_id, location, component);
|
return console.error("An invalid plugin was detected.", plugin_id, location, component);
|
||||||
}
|
}
|
||||||
updateLoadedPluginsList((prev) => {
|
updatePluginsData(prev => {
|
||||||
const filtered = prev.data.filter(item => item.plugin_id !== plugin_id);
|
const is_already_registered = prev.data.some(old_value => old_value.plugin_id === plugin_id);
|
||||||
return [...filtered, { plugin_id, location, component }];
|
const new_value = prev.data.map(old_value =>
|
||||||
|
old_value.plugin_id === plugin_id
|
||||||
|
? { ...old_value, location, component, is_downloaded: true }
|
||||||
|
: old_value
|
||||||
|
);
|
||||||
|
|
||||||
|
return is_already_registered
|
||||||
|
? new_value
|
||||||
|
: [...new_value, { plugin_id, location, component, is_downloaded: true }];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
createAtomWithHook: (...args) => createAtomWithHook(...args)
|
createAtomWithHook: (...args) => createAtomWithHook(...args)
|
||||||
@@ -66,7 +75,7 @@ export const usePlugins = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadAllPlugins = async () => {
|
const asyncLoadAllPlugins = async () => {
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
// 開発時: ホットリロード対応、src-tauri以下のpluginsから直接読み込み
|
// 開発時: ホットリロード対応、src-tauri以下のpluginsから直接読み込み
|
||||||
Object.entries(dev_plugin_mapping).forEach(([key, plugin_module]) => {
|
Object.entries(dev_plugin_mapping).forEach(([key, plugin_module]) => {
|
||||||
@@ -169,8 +178,7 @@ export const usePlugins = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const asyncUpdatePluginInfoList = async () => {
|
const asyncFetchPluginsInfo = async () => {
|
||||||
pendingPluginsInfoList();
|
|
||||||
try {
|
try {
|
||||||
const response = await asyncTauriFetchGithub(PLUGIN_LIST_URL);
|
const response = await asyncTauriFetchGithub(PLUGIN_LIST_URL);
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
@@ -194,7 +202,7 @@ export const usePlugins = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
updatePluginsInfoList(updated_list);
|
return updated_list;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching plugin info list:", error);
|
console.error("Error fetching plugin info list:", error);
|
||||||
}
|
}
|
||||||
@@ -236,22 +244,26 @@ export const usePlugins = () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setSavedPluginsStatus = (plugins_status) => {
|
||||||
|
pendingSavedPluginsStatus();
|
||||||
|
asyncStdoutToPython("/set/data/plugins_status", plugins_status);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
asyncUpdatePluginInfoList,
|
asyncFetchPluginsInfo,
|
||||||
|
|
||||||
loadAllPlugins,
|
asyncLoadAllPlugins,
|
||||||
downloadAndExtractPlugin,
|
downloadAndExtractPlugin,
|
||||||
|
|
||||||
currentLoadedPluginsList,
|
|
||||||
updateLoadedPluginsList,
|
|
||||||
|
|
||||||
currentSavedPluginsStatus,
|
currentSavedPluginsStatus,
|
||||||
updateSavedPluginsStatus,
|
updateSavedPluginsStatus,
|
||||||
|
|
||||||
currentPluginsInfoList,
|
currentPluginsData,
|
||||||
updatePluginsInfoList,
|
updatePluginsData,
|
||||||
|
|
||||||
|
setSavedPluginsStatus,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ import {
|
|||||||
useOverlayShowOnlyTranslatedMessages,
|
useOverlayShowOnlyTranslatedMessages,
|
||||||
useEnableNotificationVrcSfx,
|
useEnableNotificationVrcSfx,
|
||||||
useHotkeys,
|
useHotkeys,
|
||||||
|
usePlugins,
|
||||||
useOscIpAddress,
|
useOscIpAddress,
|
||||||
useOscPort,
|
useOscPort,
|
||||||
} from "@logics_configs";
|
} from "@logics_configs";
|
||||||
@@ -176,6 +177,7 @@ export const useReceiveRoutes = () => {
|
|||||||
const { updateEnableNotificationVrcSfx } = useEnableNotificationVrcSfx();
|
const { updateEnableNotificationVrcSfx } = useEnableNotificationVrcSfx();
|
||||||
|
|
||||||
const { updateHotkeys } = useHotkeys();
|
const { updateHotkeys } = useHotkeys();
|
||||||
|
const { updateSavedPluginsStatus } = usePlugins();
|
||||||
|
|
||||||
const { updateOscIpAddress } = useOscIpAddress();
|
const { updateOscIpAddress } = useOscIpAddress();
|
||||||
const { updateOscPort } = useOscPort();
|
const { updateOscPort } = useOscPort();
|
||||||
@@ -488,6 +490,10 @@ export const useReceiveRoutes = () => {
|
|||||||
"/get/data/hotkeys": updateHotkeys,
|
"/get/data/hotkeys": updateHotkeys,
|
||||||
"/set/data/hotkeys": updateHotkeys,
|
"/set/data/hotkeys": updateHotkeys,
|
||||||
|
|
||||||
|
// Plugins
|
||||||
|
"/get/data/plugins_status": updateSavedPluginsStatus,
|
||||||
|
"/set/data/plugins_status": updateSavedPluginsStatus,
|
||||||
|
|
||||||
// Advanced Settings
|
// Advanced Settings
|
||||||
"/get/data/osc_ip_address": updateOscIpAddress,
|
"/get/data/osc_ip_address": updateOscIpAddress,
|
||||||
"/set/data/osc_ip_address": updateOscIpAddress,
|
"/set/data/osc_ip_address": updateOscIpAddress,
|
||||||
|
|||||||
@@ -275,12 +275,9 @@ export const { atomInstance: Atom_Hotkeys, useHook: useStore_Hotkeys } = createA
|
|||||||
}, "Hotkeys");
|
}, "Hotkeys");
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
export const { atomInstance: Atom_LoadedPluginsList, useHook: useStore_LoadedPluginsList } = createAtomWithHook([], "LoadedPluginsList");
|
// export const { atomInstance: Atom_LoadedPluginsList, useHook: useStore_LoadedPluginsList } = createAtomWithHook([], "LoadedPluginsList");
|
||||||
export const { atomInstance: Atom_SavedPluginsStatus, useHook: useStore_SavedPluginsStatus } = createAtomWithHook([
|
export const { atomInstance: Atom_SavedPluginsStatus, useHook: useStore_SavedPluginsStatus } = createAtomWithHook([], "SavedPluginsStatus");
|
||||||
{ plugin_id: "vrct_plugin_example_1", is_enabled: true },
|
export const { atomInstance: Atom_PluginsData, useHook: useStore_PluginsData } = createAtomWithHook([], "PluginsData");
|
||||||
{ plugin_id: "vrct_plugin_example_2", is_enabled: false }
|
|
||||||
], "SavedPluginsStatus");
|
|
||||||
export const { atomInstance: Atom_PluginsInfoList, useHook: useStore_PluginsInfoList } = createAtomWithHook([], "PluginsInfoList");
|
|
||||||
|
|
||||||
// Advanced Settings
|
// Advanced Settings
|
||||||
export const { atomInstance: Atom_OscIpAddress, useHook: useStore_OscIpAddress } = createAtomWithHook("127.0.0.1", "OscIpAddress");
|
export const { atomInstance: Atom_OscIpAddress, useHook: useStore_OscIpAddress } = createAtomWithHook("127.0.0.1", "OscIpAddress");
|
||||||
|
|||||||
Reference in New Issue
Block a user