[Update] Plugins: Add update function.

This commit is contained in:
Sakamoto Shiina
2025-04-02 22:52:20 +09:00
parent c02d7c49e9
commit 67f32ad7b9
7 changed files with 83 additions and 52 deletions

View File

@@ -23,25 +23,43 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
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]));
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 (prevMap.has(info.plugin_id)) {
return { ...info, ...prevMap.get(info.plugin_id) };
if (prev_map.has(info.plugin_id)) {
return {
...info,
latest_plugin_version: info.plugin_version,
...prev_map.get(info.plugin_id),
};
}
return info;
return {
...info,
latest_plugin_version: info.plugin_version,
};
});
// prev.data にのみ存在するアイテムを追加し、is_outdated: true を付与
// prev.data にのみ存在するアイテム = latest plugin infoには存在しない
// を追加し、is_outdated: true を付与
prev.data.forEach(item => {
if (!infoMap.has(item.plugin_id)) {
if (!info_map.has(item.plugin_id)) {
merged.push({ ...item, is_outdated: true });
}
});
return merged;
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_value.push(plugin);
}
return new_value;
});
} catch (error) {
console.error(error);
@@ -59,7 +77,7 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
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]));
const prev_map = new Map(prev.data.map(item => [item.plugin_id, item]));
// prev.data にある各アイテムについて、保存済みの状態情報があればマージ
const merged = prev.data.map(item => {
@@ -71,7 +89,7 @@ export const PluginsController = ({ fetchPluginsHasRunRef }) => {
// currentSavedPluginsStatus.data にのみ存在する項目があれば追加
currentSavedPluginsStatus.data.forEach(saved => {
if (!prevMap.has(saved.plugin_id)) {
if (!prev_map.has(saved.plugin_id)) {
merged.push({ plugin_id: saved.plugin_id, is_enabled: saved.is_enabled });
}
});

View File

@@ -32,6 +32,15 @@ export const _DownloadButton = ({option, ...props}) => {
<p className={styles.download_button_label}>{t("config_page.model_download_button_label")}</p>
</button>
);
case option.update_button:
return (
<button
className={styles.update_button}
onClick={() => props.downloadStartFunction(option.id)}
>
<p className={styles.download_button_label}>Update</p>
</button>
);
default:
return null;
}

View File

@@ -28,4 +28,18 @@
.progress_label {
position: absolute;
font-size: 1rem;
}
.update_button {
pointer-events: auto;
background-color: var(--primary_400_color);
padding: 0.8rem;
flex-shrink: 0;
border-radius: 0.2rem;
&:hover {
background-color: var(--primary_450_color);
}
&:active {
background-color: var(--primary_500_color);
}
}

View File

@@ -1,48 +1,31 @@
import {
SwitchBox,
} from "../index";
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 }) => {
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;
const option = {
id: plugin_status.plugin_id,
is_pending: plugin_status.is_pending,
is_downloaded: plugin_status.is_downloaded,
data: plugin_status.is_enabled,
id: plugin_id,
is_pending: is_pending,
is_downloaded: is_downloaded,
data: is_enabled,
update_button: is_downloaded && is_latest_version_available,
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;
}
const togglePlugin = () => toggleFunction(plugin_id);
const is_turn_on_able = is_downloaded && (is_plugin_supported || is_outdated);
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>
}
{is_plugin_supported ? (
<_DownloadButton option={option} downloadStartFunction={downloadStartFunction} />
) : (
<div className={styles.unavailable_text}>Downloaded but outdated.</div>
)}
{is_turn_on_able && <SwitchBox variable={option} toggleFunction={togglePlugin} />}
</div>
);
};

View File

@@ -1,4 +1,8 @@
.container {
display: flex;
justify-content: center;
align-items: center;
gap: 2rem;
}
.unavailable_text {

View File

@@ -88,7 +88,8 @@ const PluginDownloadContainer = () => {
) : (
<div className={styles.plugin_info_wrapper}>
<div className={styles.plugin_info}>
<p>Version: {plugin.plugin_version}</p>
<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}
</p>

View File

@@ -47,17 +47,19 @@ export const usePlugins = () => {
return console.error("An invalid plugin was detected.", plugin_info.plugin_id, plugin_info.location, component);
}
updatePluginsData(prev => {
const is_already_registered = prev.data.some(old_value => old_value.plugin_id === plugin_info.plugin_id);
const new_value = prev.data.map(old_value =>
old_value.plugin_id === plugin_info.plugin_id
? { ...old_value, ...plugin_info, location: plugin_info.location, component, is_downloaded: true }
: old_value
? {
...old_value,
...plugin_info,
downloaded_plugin_version: plugin_info.plugin_version,
component: component,
is_downloaded: true,
is_latest_version_available: false,
} : old_value
);
return is_already_registered
? new_value
: [...new_value, { plugin_id: plugin_info.plugin_id, location: plugin_info.location, component, is_downloaded: true }];
return new_value;
});
},
createAtomWithHook: (...args) => createAtomWithHook(...args),