[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:
Sakamoto Shiina
2025-04-09 17:29:31 +09:00
parent 67f32ad7b9
commit 7e637b795d
18 changed files with 404 additions and 180 deletions

View File

@@ -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>
);
}
};

View File

@@ -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>
);
};
};

View File

@@ -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";