[Update/Refactor/bugfix]
Update: Add functions and test ui. Update, backend: send latest vrct version to frontend. Refactor: Change the plugins data structure. bugfix: fix endless showing update button.
This commit is contained in:
@@ -14,6 +14,7 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
|
||||
currentPluginsData,
|
||||
updatePluginsData,
|
||||
currentSavedPluginsStatus,
|
||||
updateIsPluginsInitialized,
|
||||
} = usePlugins();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -26,40 +27,55 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
|
||||
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]));
|
||||
|
||||
// info_array にある各アイテムについて、prev.data に同じ plugin_id があればマージ
|
||||
const merged = info_array.map(info => {
|
||||
if (prev_map.has(info.plugin_id)) {
|
||||
return {
|
||||
...info,
|
||||
latest_plugin_version: info.plugin_version,
|
||||
...prev_map.get(info.plugin_id),
|
||||
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 = {
|
||||
is_downloaded: true,
|
||||
is_latest_version_already: (target_downloaded_plugin.downloaded_plugin_info?.plugin_version === info.plugin_version),
|
||||
is_latest_version_available: is_latest_version_available,
|
||||
latest_plugin_info: { ...info },
|
||||
...target_downloaded_plugin,
|
||||
};
|
||||
} else { // infoにもあり登録済みだがダウンロードされていない
|
||||
new_plugin_info = {
|
||||
is_downloaded: false,
|
||||
is_latest_version_already: false,
|
||||
is_latest_version_available: info.is_latest_version_available,
|
||||
latest_plugin_info: { ...info },
|
||||
...target_downloaded_plugin,
|
||||
}
|
||||
}
|
||||
} else { // 未ダウンロード
|
||||
new_plugin_info = {
|
||||
plugin_id: info.plugin_id,
|
||||
is_downloaded: false,
|
||||
is_latest_version_already: false,
|
||||
latest_plugin_info: { ...info },
|
||||
};
|
||||
}
|
||||
return {
|
||||
...info,
|
||||
latest_plugin_version: info.plugin_version,
|
||||
};
|
||||
});
|
||||
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)) {
|
||||
merged.push({ ...item, is_outdated: true });
|
||||
new_data.push({ ...item, is_outdated: true });
|
||||
}
|
||||
});
|
||||
|
||||
let new_value = [];
|
||||
for (const plugin of merged) {
|
||||
if (plugin.downloaded_plugin_version !== plugin.latest_plugin_version && plugin.is_plugin_supported) {
|
||||
plugin.is_latest_version_available = true;
|
||||
} else {
|
||||
plugin.is_latest_version_available = false;
|
||||
new_data.forEach(plugin => {
|
||||
if (!plugin.is_outdated) {
|
||||
plugin.is_latest_version_available = (plugin.latest_plugin_info.is_plugin_supported);
|
||||
}
|
||||
new_value.push(plugin);
|
||||
}
|
||||
|
||||
return new_value;
|
||||
});
|
||||
return new_data;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
@@ -68,6 +84,7 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
|
||||
|
||||
if (!fetchPluginsHasRunRef.current) {
|
||||
loadPlugins();
|
||||
updateIsPluginsInitialized(true);
|
||||
}
|
||||
return () => fetchPluginsHasRunRef.current = true;
|
||||
}, []);
|
||||
@@ -76,13 +93,13 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
|
||||
useEffect(() => {
|
||||
updatePluginsData(prev => {
|
||||
// currentSavedPluginsStatus.data の各要素を Map 化して plugin_id で参照
|
||||
const savedMap = new Map(currentSavedPluginsStatus.data.map(saved => [saved.plugin_id, saved]));
|
||||
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 (savedMap.has(item.plugin_id)) {
|
||||
return { ...item, is_enabled: savedMap.get(item.plugin_id).is_enabled };
|
||||
|
||||
if (saved_map.has(item.plugin_id)) {
|
||||
return { ...item, is_enabled: saved_map.get(item.plugin_id).is_enabled };
|
||||
}
|
||||
return item;
|
||||
});
|
||||
@@ -93,7 +110,6 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
|
||||
merged.push({ plugin_id: saved.plugin_id, is_enabled: saved.is_enabled });
|
||||
}
|
||||
});
|
||||
|
||||
return merged;
|
||||
});
|
||||
}, [currentSavedPluginsStatus]);
|
||||
|
||||
@@ -1,31 +1,136 @@
|
||||
import React from "react";
|
||||
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, downloadStartFunction }) => {
|
||||
const { plugin_id, is_pending, is_downloaded, is_enabled, is_latest_version_available, is_plugin_supported, is_outdated } = plugin_status;
|
||||
|
||||
// メインのコントロールコンポーネント。ダウンロード済み / 未ダウンロードで分岐して表示する
|
||||
export const PluginsControlComponent = ({
|
||||
variable_state,
|
||||
plugin_status,
|
||||
toggleFunction,
|
||||
downloadStartFunction,
|
||||
}) => {
|
||||
// 共通オプション(各子コンポーネントに引き回す情報)
|
||||
const option = {
|
||||
id: plugin_id,
|
||||
is_pending: is_pending,
|
||||
is_downloaded: is_downloaded,
|
||||
data: is_enabled,
|
||||
update_button: is_downloaded && is_latest_version_available,
|
||||
id: plugin_status.plugin_id,
|
||||
is_pending: plugin_status.is_pending,
|
||||
is_downloaded: plugin_status.is_downloaded,
|
||||
data: plugin_status.is_enabled,
|
||||
update_button: plugin_status.is_downloaded && plugin_status.is_latest_version_available,
|
||||
state: variable_state,
|
||||
progress: null,
|
||||
};
|
||||
|
||||
const togglePlugin = () => toggleFunction(plugin_id);
|
||||
const is_turn_on_able = is_downloaded && (is_plugin_supported || is_outdated);
|
||||
if (plugin_status.is_downloaded) {
|
||||
return (
|
||||
<DownloadedPluginControl
|
||||
option={option}
|
||||
plugin_status={plugin_status}
|
||||
toggleFunction={toggleFunction}
|
||||
downloadStartFunction={downloadStartFunction}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<NotDownloadedPluginControl
|
||||
option={option}
|
||||
plugin_status={plugin_status}
|
||||
downloadStartFunction={downloadStartFunction}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{is_plugin_supported ? (
|
||||
// -------------------------
|
||||
// ダウンロード済みのプラグイン用コンポーネント
|
||||
// 状態により以下の分岐を行う
|
||||
// ・ is_latest_version_already が true なら「最新版を使用中」
|
||||
// ・ is_latest_version_already が false かつ is_latest_version_available が true なら「最新版を利用可能」(アップデートボタン+スイッチ)
|
||||
// ・ それ以外(is_latest_version_already:false && is_latest_version_available: false)なら、desc等の情報とスイッチのみ表示
|
||||
const DownloadedPluginControl = ({
|
||||
option,
|
||||
plugin_status,
|
||||
toggleFunction,
|
||||
downloadStartFunction,
|
||||
}) => {
|
||||
// on/off トグル時の処理
|
||||
const togglePlugin = () => {
|
||||
toggleFunction(plugin_status.plugin_id);
|
||||
};
|
||||
|
||||
|
||||
// ダウンロード済みの場合、ダウンロードされた情報からタイトルやバージョンを取得
|
||||
const title = plugin_status.downloaded_plugin_info?.title || plugin_status.latest_plugin_info.title;
|
||||
const current_version =
|
||||
plugin_status.downloaded_plugin_info?.plugin_version || plugin_status.latest_plugin_info.plugin_version;
|
||||
|
||||
// コンポーネントごとに表示内容を分岐
|
||||
if (plugin_status.is_latest_version_already) {
|
||||
// 最新版が既に使用中
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<p>{title}</p>
|
||||
<p>現在のバージョン: {current_version}</p>
|
||||
<p>最新版を使用中</p>
|
||||
<SwitchBox variable={option} toggleFunction={togglePlugin} />
|
||||
</div>
|
||||
);
|
||||
} else if (plugin_status.is_latest_version_available) {
|
||||
// 最新版の利用可能なお知らせとアップデートボタン+スイッチ
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<p>{title}</p>
|
||||
<p>現在のバージョン: {current_version}</p>
|
||||
<p>最新版を利用可能</p>
|
||||
<_DownloadButton option={option} downloadStartFunction={downloadStartFunction} />
|
||||
) : (
|
||||
<div className={styles.unavailable_text}>Downloaded but outdated.</div>
|
||||
)}
|
||||
{is_turn_on_able && <SwitchBox variable={option} toggleFunction={togglePlugin} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
<SwitchBox variable={option} toggleFunction={togglePlugin} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
// 最新版利用可能ではないがダウンロード済み
|
||||
// ※「desc」に関しては、情報があればplugin_status.descやlatest_plugin_info.descを利用してください
|
||||
const desc =
|
||||
plugin_status.latest_plugin_info.desc ||
|
||||
"追加情報がありません。";
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<p>{title}</p>
|
||||
<p>現在のバージョン: {current_version}</p>
|
||||
<p>{desc}</p>
|
||||
<SwitchBox variable={option} toggleFunction={togglePlugin} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------
|
||||
// 未ダウンロードのプラグイン用コンポーネント
|
||||
// 状態により以下の分岐を行う
|
||||
// ・ is_latest_version_available が true なら:info_title, 最新バージョン情報とダウンロードボタン
|
||||
// ・ is_latest_version_available が false なら:info_title, 最新バージョン情報と「現在利用不可」
|
||||
const NotDownloadedPluginControl = ({ option, plugin_status, downloadStartFunction }) => {
|
||||
const title = plugin_status.latest_plugin_info.title;
|
||||
const latest_version = plugin_status.latest_plugin_info.plugin_version;
|
||||
// ※未ダウンロードの場合、current_versionは「未ダウンロード」や「なし」といった扱いとする
|
||||
const current_version = "未ダウンロード";
|
||||
|
||||
if (plugin_status.is_latest_version_available) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<p>{title}</p>
|
||||
<p>現在のバージョン: {current_version}</p>
|
||||
<p>最新バージョン: {latest_version}</p>
|
||||
<_DownloadButton option={option} downloadStartFunction={downloadStartFunction} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<p>{title}</p>
|
||||
<p>現在のバージョン: {current_version}</p>
|
||||
<p>最新バージョン: {latest_version}</p>
|
||||
<p>現在利用不可</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { usePlugins } from "@logics_configs";
|
||||
import styles from "./Plugins.module.scss";
|
||||
import { PluginsControlComponent } from "../_components";
|
||||
import { PluginsControlComponent } from "../_components/plugins_control_component/PluginsControlComponent";
|
||||
|
||||
export const Plugins = () => {
|
||||
const {
|
||||
currentIsPluginsInitialized,
|
||||
} = usePlugins();
|
||||
|
||||
if (!currentIsPluginsInitialized.data) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<PluginDownloadContainer />
|
||||
@@ -11,6 +17,7 @@ export const Plugins = () => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const PluginDownloadContainer = () => {
|
||||
const {
|
||||
downloadAndExtractPlugin,
|
||||
@@ -18,40 +25,29 @@ const PluginDownloadContainer = () => {
|
||||
updatePluginsData,
|
||||
currentSavedPluginsStatus,
|
||||
setSavedPluginsStatus,
|
||||
handlePendingPlugin,
|
||||
} = usePlugins();
|
||||
|
||||
|
||||
// ダウンロード開始時の状態更新処理
|
||||
const downloadStartFunction = async (target_plugin_id) => {
|
||||
updatePluginsData((old_value) => {
|
||||
const new_value = old_value.data.map(d => {
|
||||
if (d.plugin_id === target_plugin_id) {
|
||||
d.is_pending = true;
|
||||
}
|
||||
return d;
|
||||
});
|
||||
return new_value;
|
||||
});
|
||||
const target_plugin_info = currentPluginsData.data.find(d => d.plugin_id === target_plugin_id);
|
||||
handlePendingPlugin(target_plugin_id, true);
|
||||
|
||||
const target_plugin_info = currentPluginsData.data.find(
|
||||
(d) => d.plugin_id === target_plugin_id
|
||||
);
|
||||
downloadAndExtractPlugin(target_plugin_info).then(() => {
|
||||
updatePluginsData((old_value) => {
|
||||
const new_value = old_value.data.map(d => {
|
||||
if (d.plugin_id === target_plugin_id) {
|
||||
d.is_pending = false;
|
||||
d.is_downloaded = true;
|
||||
}
|
||||
return d;
|
||||
});
|
||||
return new_value;
|
||||
});
|
||||
})
|
||||
handlePendingPlugin(target_plugin_id, false);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// プラグインのオンオフ切り替え処理
|
||||
const toggleFunction = (target_plugin_id) => {
|
||||
const is_exists = currentSavedPluginsStatus.data.some(d => d.plugin_id === target_plugin_id);
|
||||
const is_exists = currentSavedPluginsStatus.data.some(
|
||||
(d) => d.plugin_id === target_plugin_id
|
||||
);
|
||||
let new_value = [];
|
||||
if (is_exists) {
|
||||
new_value = currentSavedPluginsStatus.data.map(d => {
|
||||
new_value = currentSavedPluginsStatus.data.map((d) => {
|
||||
if (d.plugin_id === target_plugin_id) {
|
||||
d.is_enabled = !d.is_enabled;
|
||||
}
|
||||
@@ -65,40 +61,45 @@ const PluginDownloadContainer = () => {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
});
|
||||
// 「currentPluginsData.data」でis_downloadedがtrueのものだけ残す
|
||||
new_value = new_value.filter((item) =>
|
||||
currentPluginsData.data.some(
|
||||
(plugin) => plugin.plugin_id === item.plugin_id && plugin.is_downloaded
|
||||
)
|
||||
);
|
||||
|
||||
setSavedPluginsStatus(new_value);
|
||||
}
|
||||
};
|
||||
|
||||
const variable_state = currentSavedPluginsStatus.state;
|
||||
|
||||
|
||||
return (
|
||||
<div className={styles.plugins_list_container}>
|
||||
{currentPluginsData.data.map((plugin) => (
|
||||
<div key={plugin.plugin_id} className={styles.plugin_wrapper}>
|
||||
<p className={styles.title}>{plugin.title}</p>
|
||||
<p className={styles.title}>
|
||||
{plugin.is_downloaded
|
||||
? plugin.downloaded_plugin_info?.title || plugin.latest_plugin_info.title
|
||||
: plugin.latest_plugin_info.title}
|
||||
</p>
|
||||
<p className={styles.plugin_id}>{plugin.plugin_id}</p>
|
||||
{plugin.error ? (
|
||||
<p style={{ color: "red" }}>Error: {plugin.error}</p>
|
||||
) : (
|
||||
<div className={styles.plugin_info_wrapper}>
|
||||
<div className={styles.plugin_info}>
|
||||
<p>Downloaded Version: {plugin.downloaded_plugin_version}</p>
|
||||
<p>Latest Version: {plugin.latest_plugin_version}</p>
|
||||
{/* 状態に応じた情報表示(例:バージョン等) */}
|
||||
<p>
|
||||
Compatible: {plugin.min_supported_vrct_version} ~ {plugin.max_supported_vrct_version}
|
||||
{plugin.is_downloaded
|
||||
? `現在のバージョン: ${plugin.downloaded_plugin_info?.plugin_version}`
|
||||
: `最新バージョン: ${plugin.latest_plugin_info.plugin_version}`}
|
||||
</p>
|
||||
</div>
|
||||
<PluginsControlComponent
|
||||
variable_state={variable_state}
|
||||
toggleFunction={toggleFunction}
|
||||
plugin_status={plugin}
|
||||
downloadStartFunction={downloadStartFunction}
|
||||
plugin_status={plugin}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -106,4 +107,4 @@ const PluginDownloadContainer = () => {
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,8 +3,7 @@ import { useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import styles from "./VersionLabel.module.scss";
|
||||
|
||||
import { useSoftwareVersion } from "@logics_configs";
|
||||
import { useComputeMode } from "@logics_common";
|
||||
import { useSoftwareVersion, useComputeMode } from "@logics_common";
|
||||
import CopySvg from "@images/copy.svg?react";
|
||||
import CheckMarkSvg from "@images/check_mark.svg?react";
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { usePlugins } from "@logics_configs";
|
||||
export const MainSection = () => {
|
||||
const { currentPluginsData } = usePlugins();
|
||||
|
||||
const render_plugins = currentPluginsData.data.filter((plugin) => plugin.is_enabled && plugin.location === "main_section");
|
||||
const render_plugins = currentPluginsData.data.filter((plugin) => (plugin.is_downloaded && plugin.is_enabled && plugin.downloaded_plugin_info.location === "main_section"));
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
|
||||
@@ -4,7 +4,7 @@ import RefreshSvg from "@images/refresh.svg?react";
|
||||
import HelpSvg from "@images/help.svg?react";
|
||||
|
||||
import { useStore_OpenedQuickSetting } from "@store";
|
||||
import { useIsSoftwareUpdateAvailable } from "@logics_common";
|
||||
import { useSoftwareVersion } from "@logics_common";
|
||||
import { useIsEnabledOverlaySmallLog, useIsEnabledOverlayLargeLog, useEnableVrcMicMuteSync } from "@logics_configs";
|
||||
import { OpenQuickSettingButton } from "./_buttons/OpenQuickSettingButton";
|
||||
|
||||
@@ -66,9 +66,9 @@ const OpenVrcMicMuteSyncQuickSetting = () => {
|
||||
};
|
||||
|
||||
const SoftwareUpdateAvailableButton = () => {
|
||||
const { currentIsSoftwareUpdateAvailable } = useIsSoftwareUpdateAvailable();
|
||||
const { currentLatestSoftwareVersionInfo } = useSoftwareVersion();
|
||||
const { t } = useTranslation();
|
||||
if (currentIsSoftwareUpdateAvailable.data === false) return null;
|
||||
if (currentLatestSoftwareVersionInfo.data.is_update_available === false) return null;
|
||||
|
||||
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import styles from "./UpdateModal.module.scss";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useStore_OpenedQuickSetting } from "@store";
|
||||
import { useComputeMode, useUpdateSoftware } from "@logics_common";
|
||||
import { useIsSoftwareUpdating, useIsSoftwareUpdateAvailable } from "@logics_common";
|
||||
import { usePlugins } from "@logics_configs";
|
||||
import {
|
||||
useComputeMode,
|
||||
useUpdateSoftware,
|
||||
useIsSoftwareUpdating,
|
||||
useSoftwareVersion,
|
||||
} from "@logics_common";
|
||||
|
||||
import clsx from "clsx";
|
||||
|
||||
export const UpdateModal = () => {
|
||||
@@ -11,9 +17,13 @@ export const UpdateModal = () => {
|
||||
const { updateSoftware, updateSoftware_CUDA } = useUpdateSoftware();
|
||||
const { updateIsSoftwareUpdating } = useIsSoftwareUpdating();
|
||||
const { currentComputeMode } = useComputeMode();
|
||||
const { currentIsSoftwareUpdateAvailable } = useIsSoftwareUpdateAvailable();
|
||||
const { currentLatestSoftwareVersionInfo } = useSoftwareVersion();
|
||||
const { isAnyPluginEnabled } = usePlugins();
|
||||
|
||||
const is_latest_version_already = currentIsSoftwareUpdateAvailable.data === false;
|
||||
console.log(isAnyPluginEnabled());
|
||||
|
||||
|
||||
const is_latest_version_already = currentLatestSoftwareVersionInfo.data.is_update_available === false;
|
||||
const is_cpu_version = currentComputeMode.data === "cpu";
|
||||
|
||||
const onClickUpdateSoftware = () => {
|
||||
@@ -37,6 +47,7 @@ export const UpdateModal = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.wrapper}>
|
||||
{isAnyPluginEnabled() && <PluginUpdateNotification />}
|
||||
<div className={styles.update_section}>
|
||||
<div className={styles.cpu_section}>
|
||||
<div className={styles.button_wrapper}>
|
||||
@@ -85,4 +96,20 @@ const CurrentVersionLabel = (props) => {
|
||||
return <p className={clsx(styles.current_version_label, {[styles.is_cuda]: props.is_cuda})}>{t("update_modal.is_latest_version_already")}</p>;
|
||||
}
|
||||
return <p className={clsx(styles.current_version_label, {[styles.is_cuda]: props.is_cuda})}>{t("update_modal.is_current_compute_device")}</p>;
|
||||
};
|
||||
|
||||
const PluginUpdateNotification = () => {
|
||||
const { enabledPluginsList } = usePlugins();
|
||||
|
||||
const incompatible_plugins_list = enabledPluginsList();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{incompatible_plugins_list.map(plugin => {
|
||||
console.log(plugin);
|
||||
|
||||
return <p>{plugin.title}</p>
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user