Add cell list to plugin detail page

Also add mod counts in parenthesis.
This commit is contained in:
Tyler Hallada 2022-03-14 21:55:52 -04:00
parent e7e392a7b7
commit a590dbd02c
6 changed files with 91 additions and 54 deletions

View File

@ -10,7 +10,7 @@ type Props = {
cells: CellCoord[];
};
const ModCellList: React.FC<Props> = ({ cells }) => {
const CellList: React.FC<Props> = ({ cells }) => {
return (
cells && (
<>
@ -44,4 +44,4 @@ const ModCellList: React.FC<Props> = ({ cells }) => {
);
};
export default ModCellList;
export default CellList;

View File

@ -34,7 +34,7 @@ const CellModList: React.FC<Props> = ({ mods, counts }) => {
return (
mods && (
<>
<h2>Mods</h2>
<h2>Mods ({modsWithCounts.length})</h2>
<ul className={styles["mod-list"]}>
{modsWithCounts
.sort((a, b) => b.unique_downloads - a.unique_downloads)

View File

@ -362,7 +362,12 @@ const Map: React.FC = () => {
]);
useEffect(() => {
if (router.query.plugin && typeof router.query.plugin === "string" && fetchedPlugin && fetchedPlugin.cells) {
if (
router.query.plugin &&
typeof router.query.plugin === "string" &&
fetchedPlugin &&
fetchedPlugin.cells
) {
const cells = [];
const cellSet = new Set<number>();
for (const cell of fetchedPlugin.cells) {

View File

@ -3,7 +3,7 @@ import Head from "next/head";
import React from "react";
import useSWRImmutable from "swr/immutable";
import ModCellList from "./ModCellList";
import CellList from "./CellList";
import styles from "../styles/ModData.module.css";
export interface CellCoord {
@ -160,7 +160,7 @@ const ModData: React.FC<Props> = ({
<strong>Unique Downloads:</strong>{" "}
{numberFmt.format(unique_downloads)}
</div>
<ModCellList cells={data.cells} />
<CellList cells={data.cells} />
</>
);
}

View File

@ -2,12 +2,20 @@ import React, { useEffect } from "react";
import useSWRImmutable from "swr/immutable";
import { useAppDispatch, useAppSelector } from "../lib/hooks";
import { setFetchedPlugin, PluginFile, PluginsByHashWithMods, Cell } from "../slices/plugins";
import {
setFetchedPlugin,
PluginFile,
PluginsByHashWithMods,
} from "../slices/plugins";
import PluginModList from "./PluginModList";
import CellList from "./CellList";
import type { CellCoord } from "./ModData";
import PluginData, { Plugin as PluginProps } from "./PluginData";
import styles from "../styles/PluginData.module.css";
const jsonFetcher = async (url: string): Promise<PluginsByHashWithMods | null> => {
const jsonFetcher = async (
url: string
): Promise<PluginsByHashWithMods | null> => {
const res = await fetch(url);
if (!res.ok) {
@ -20,18 +28,34 @@ const jsonFetcher = async (url: string): Promise<PluginsByHashWithMods | null> =
return res.json();
};
const buildPluginProps = (data?: PluginsByHashWithMods | null, plugin?: PluginFile): PluginProps => {
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)) || "",
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) || [],
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,
}
}
cell_count:
plugin?.parsed?.cells.length || (data && data.cells.length) || 0,
};
};
type Props = {
hash: string;
@ -53,7 +77,7 @@ const PluginDetail: React.FC<Props> = ({ hash, counts }) => {
if (data) {
dispatch(setFetchedPlugin(data));
}
}, [dispatch, data, fetchedPlugin])
}, [dispatch, data, fetchedPlugin]);
if (!plugin && error && error.status === 404) {
return <h3>Plugin could not be found.</h3>;
@ -67,11 +91,22 @@ const PluginDetail: React.FC<Props> = ({ hash, counts }) => {
return (
<>
<PluginData
plugin={buildPluginProps(data, plugin)}
counts={counts}
<PluginData plugin={buildPluginProps(data, plugin)} counts={counts} />
{data && (
<PluginModList mods={data.mods} files={data.files} counts={counts} />
)}
<CellList
cells={
(plugin?.parsed?.cells.filter(
(cell) =>
cell.x !== undefined &&
cell.y !== undefined &&
cell.world_form_id === 60
) as CellCoord[]) ||
data?.cells ||
[]
}
/>
{data && <PluginModList mods={data.mods} files={data.files} counts={counts} />}
</>
);
};

View File

@ -37,7 +37,7 @@ const PluginModList: React.FC<Props> = ({ mods, files, counts }) => {
return (
mods && (
<>
<h2>Mods</h2>
<h2>Mods ({modsWithCounts.length})</h2>
<ul className={styles["mod-list"]}>
{modsWithCounts
.sort((a, b) => b.unique_downloads - a.unique_downloads)
@ -96,33 +96,30 @@ const PluginModList: React.FC<Props> = ({ mods, files, counts }) => {
{numberFmt.format(mod.unique_downloads)}
</div>
<ul className={styles["file-list"]}>
{files.filter(file => file.mod_id === mod.id).map(file => (
{files
.filter((file) => file.mod_id === mod.id)
.map((file) => (
<li key={file.id}>
<div>
<strong>File:</strong>{" "}
{file.name}
<strong>File:</strong> {file.name}
</div>
{file.mod_version && (
<div>
<strong>Version:</strong>{" "}
{file.mod_version}
<strong>Version:</strong> {file.mod_version}
</div>
)}
{file.version && file.mod_version !== file.version && (
<div>
<strong>File Version:</strong>{" "}
{file.version}
<strong>File Version:</strong> {file.version}
</div>
)}
{file.category && (
<div>
<strong>Category:</strong>{" "}
{file.category}
<strong>Category:</strong> {file.category}
</div>
)}
<div>
<strong>Size:</strong>{" "}
{formatBytes(file.size)}
<strong>Size:</strong> {formatBytes(file.size)}
</div>
{file.uploaded_at && (
<div>