2022-03-12 23:34:45 +00:00
|
|
|
import React, { useEffect } from "react";
|
2022-03-11 04:41:43 +00:00
|
|
|
import useSWRImmutable from "swr/immutable";
|
|
|
|
|
2022-03-12 23:34:45 +00:00
|
|
|
import { useAppDispatch, useAppSelector } from "../lib/hooks";
|
2022-03-15 01:55:52 +00:00
|
|
|
import {
|
2022-08-19 23:37:38 +00:00
|
|
|
setSelectedFetchedPlugin,
|
2022-03-15 01:55:52 +00:00
|
|
|
PluginFile,
|
|
|
|
PluginsByHashWithMods,
|
2022-08-19 23:37:38 +00:00
|
|
|
updateFetchedPlugin,
|
|
|
|
removeFetchedPlugin,
|
2022-03-15 01:55:52 +00:00
|
|
|
} from "../slices/plugins";
|
2022-03-17 05:11:59 +00:00
|
|
|
import ModList from "./ModList";
|
2022-03-15 01:55:52 +00:00
|
|
|
import CellList from "./CellList";
|
|
|
|
import type { CellCoord } from "./ModData";
|
2022-03-12 19:00:40 +00:00
|
|
|
import PluginData, { Plugin as PluginProps } from "./PluginData";
|
2022-03-19 03:41:06 +00:00
|
|
|
import styles from "../styles/PluginDetail.module.css";
|
2022-03-18 05:06:20 +00:00
|
|
|
import { jsonFetcher } from "../lib/api";
|
2022-03-11 04:41:43 +00:00
|
|
|
|
2022-03-15 01:55:52 +00:00
|
|
|
const buildPluginProps = (
|
|
|
|
data?: PluginsByHashWithMods | null,
|
|
|
|
plugin?: PluginFile
|
|
|
|
): PluginProps => {
|
2022-03-12 19:00:40 +00:00
|
|
|
const dataPlugin = data && data.plugins.length > 0 && data.plugins[0];
|
|
|
|
return {
|
2022-03-15 01:55:52 +00:00
|
|
|
hash:
|
|
|
|
(plugin && plugin.hash) ||
|
|
|
|
(dataPlugin && dataPlugin.hash.toString(36)) ||
|
|
|
|
"",
|
2022-03-12 19:00:40 +00:00
|
|
|
size: plugin?.size || (dataPlugin && dataPlugin.size) || 0,
|
2022-03-15 01:55:52 +00:00
|
|
|
author:
|
|
|
|
plugin?.parsed?.header.author ||
|
|
|
|
(dataPlugin && dataPlugin.author) ||
|
|
|
|
undefined,
|
|
|
|
description:
|
|
|
|
plugin?.parsed?.header.description ||
|
|
|
|
(dataPlugin && dataPlugin.description) ||
|
|
|
|
undefined,
|
|
|
|
masters:
|
|
|
|
plugin?.parsed?.header.masters ||
|
|
|
|
(dataPlugin && dataPlugin.masters) ||
|
|
|
|
[],
|
2022-03-12 19:00:40 +00:00
|
|
|
file_name: plugin?.filename || (dataPlugin && dataPlugin.file_name) || "",
|
2022-03-15 01:55:52 +00:00
|
|
|
cell_count:
|
|
|
|
plugin?.parsed?.cells.length || (data && data.cells.length) || 0,
|
|
|
|
};
|
|
|
|
};
|
2022-03-12 19:00:40 +00:00
|
|
|
|
2022-03-11 04:41:43 +00:00
|
|
|
type Props = {
|
|
|
|
hash: string;
|
|
|
|
counts: Record<number, [number, number, number]> | null;
|
|
|
|
};
|
|
|
|
|
|
|
|
const PluginDetail: React.FC<Props> = ({ hash, counts }) => {
|
|
|
|
const { data, error } = useSWRImmutable(
|
|
|
|
`https://plugins.modmapper.com/${hash}.json`,
|
2022-03-18 05:06:20 +00:00
|
|
|
(_) => jsonFetcher<PluginsByHashWithMods>(_)
|
2022-03-11 04:41:43 +00:00
|
|
|
);
|
|
|
|
|
2022-03-12 23:34:45 +00:00
|
|
|
const dispatch = useAppDispatch();
|
2022-08-19 23:37:38 +00:00
|
|
|
const parsedPlugin = useAppSelector((state) =>
|
|
|
|
state.plugins.parsedPlugins.find((plugin) => plugin.hash === hash)
|
|
|
|
);
|
|
|
|
const fetchedPlugin = useAppSelector((state) =>
|
|
|
|
state.plugins.fetchedPlugins.find((plugin) => plugin.hash === hash)
|
|
|
|
);
|
2022-03-11 04:41:43 +00:00
|
|
|
|
2022-03-12 23:34:45 +00:00
|
|
|
useEffect(() => {
|
2022-03-13 02:29:40 +00:00
|
|
|
if (data) {
|
2022-08-19 23:37:38 +00:00
|
|
|
dispatch(setSelectedFetchedPlugin(data));
|
2022-03-12 23:34:45 +00:00
|
|
|
}
|
2022-08-19 23:37:38 +00:00
|
|
|
}, [dispatch, data]);
|
2022-03-12 23:34:45 +00:00
|
|
|
|
2022-08-19 23:37:38 +00:00
|
|
|
if (!parsedPlugin && error && error.status === 404) {
|
2022-03-11 04:41:43 +00:00
|
|
|
return <h3>Plugin could not be found.</h3>;
|
2022-08-19 23:37:38 +00:00
|
|
|
} else if (!parsedPlugin && error) {
|
2022-03-11 04:41:43 +00:00
|
|
|
return <div>{`Error loading plugin data: ${error.message}`}</div>;
|
|
|
|
}
|
2022-08-19 23:37:38 +00:00
|
|
|
if (!parsedPlugin && data === undefined)
|
2022-03-11 04:41:43 +00:00
|
|
|
return <div className={styles.status}>Loading...</div>;
|
2022-08-19 23:37:38 +00:00
|
|
|
if (!parsedPlugin && data === null)
|
2022-03-11 04:41:43 +00:00
|
|
|
return <div className={styles.status}>Plugin could not be found.</div>;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2022-08-19 23:37:38 +00:00
|
|
|
<PluginData
|
|
|
|
plugin={buildPluginProps(data, parsedPlugin)}
|
|
|
|
counts={counts}
|
|
|
|
/>
|
|
|
|
{data && (
|
|
|
|
<button
|
|
|
|
className={styles.button}
|
|
|
|
onClick={() =>
|
|
|
|
fetchedPlugin
|
|
|
|
? dispatch(removeFetchedPlugin(data.hash))
|
|
|
|
: dispatch(updateFetchedPlugin(data))
|
|
|
|
}
|
|
|
|
>
|
|
|
|
{Boolean(fetchedPlugin) ? "Remove plugin" : "Add plugin"}
|
|
|
|
</button>
|
|
|
|
)}
|
2022-03-17 05:11:59 +00:00
|
|
|
{data && <ModList mods={data.mods} files={data.files} counts={counts} />}
|
2022-08-19 23:37:38 +00:00
|
|
|
{parsedPlugin?.parseError && (
|
2022-03-19 03:41:06 +00:00
|
|
|
<div className={styles.error}>
|
2022-08-19 23:37:38 +00:00
|
|
|
{`Error parsing plugin: ${parsedPlugin.parseError}`}
|
2022-03-19 03:41:06 +00:00
|
|
|
</div>
|
|
|
|
)}
|
2022-03-15 01:55:52 +00:00
|
|
|
<CellList
|
|
|
|
cells={
|
2022-08-19 23:37:38 +00:00
|
|
|
(parsedPlugin?.parsed?.cells.filter(
|
2022-03-15 01:55:52 +00:00
|
|
|
(cell) =>
|
|
|
|
cell.x !== undefined &&
|
|
|
|
cell.y !== undefined &&
|
2022-03-19 19:28:10 +00:00
|
|
|
cell.world_form_id === 60 &&
|
2022-08-19 23:37:38 +00:00
|
|
|
parsedPlugin.parsed?.header.masters[0] === "Skyrim.esm"
|
2022-03-15 01:55:52 +00:00
|
|
|
) as CellCoord[]) ||
|
|
|
|
data?.cells ||
|
|
|
|
[]
|
|
|
|
}
|
2022-03-11 04:41:43 +00:00
|
|
|
/>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default PluginDetail;
|