modmapper-web/components/PluginDetail.tsx

81 lines
2.8 KiB
TypeScript
Raw Normal View History

import React, { useEffect } from "react";
import useSWRImmutable from "swr/immutable";
import { useAppDispatch, useAppSelector } from "../lib/hooks";
import { setFetchedPlugin, PluginFile, PluginsByHashWithMods, Cell } from "../slices/plugins";
2022-03-12 19:00:40 +00:00
import CellModList from "./CellModList";
import PluginData, { Plugin as PluginProps } from "./PluginData";
import styles from "../styles/PluginData.module.css";
2022-03-12 19:00:40 +00:00
const jsonFetcher = async (url: string): Promise<PluginsByHashWithMods | null> => {
const res = await fetch(url);
if (!res.ok) {
if (res.status === 404) {
return null;
}
const error = new Error("An error occurred while fetching the data.");
throw error;
}
return res.json();
};
2022-03-12 19:00:40 +00:00
const buildPluginProps = (data?: PluginsByHashWithMods | null, plugin?: PluginFile): PluginProps => {
const dataPlugin = data && data.plugins.length > 0 && data.plugins[0];
return {
hash: (plugin && plugin.hash) || (dataPlugin && dataPlugin.hash.toString(36)) || "",
size: plugin?.size || (dataPlugin && dataPlugin.size) || 0,
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) || [],
file_name: plugin?.filename || (dataPlugin && dataPlugin.file_name) || "",
cell_count: plugin?.parsed?.cells.length || (data && data.cells.length) || 0,
}
}
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`,
jsonFetcher
);
const dispatch = useAppDispatch();
const plugins = useAppSelector((state) => state.plugins.plugins);
const fetchedPlugin = useAppSelector((state) => state.plugins.fetchedPlugin);
const plugin = plugins.find((plugin) => plugin.hash === hash);
useEffect(() => {
if (data && !fetchedPlugin) {
console.log("setting fetched plugins from PluginDetail", data);
dispatch(setFetchedPlugin(data));
}
}, [dispatch, data, fetchedPlugin])
if (!plugin && error && error.status === 404) {
return <h3>Plugin could not be found.</h3>;
} else if (!plugin && error) {
return <div>{`Error loading plugin data: ${error.message}`}</div>;
}
if (!plugin && data === undefined)
return <div className={styles.status}>Loading...</div>;
if (!plugin && data === null)
return <div className={styles.status}>Plugin could not be found.</div>;
return (
<>
<PluginData
2022-03-12 19:00:40 +00:00
plugin={buildPluginProps(data, plugin)}
counts={counts}
/>
2022-03-12 19:00:40 +00:00
{data && <CellModList mods={data.mods} counts={counts} />}
</>
);
};
export default PluginDetail;