Add cell list to plugin detail page
Also add mod counts in parenthesis.
This commit is contained in:
parent
e7e392a7b7
commit
a590dbd02c
@ -10,7 +10,7 @@ type Props = {
|
|||||||
cells: CellCoord[];
|
cells: CellCoord[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModCellList: React.FC<Props> = ({ cells }) => {
|
const CellList: React.FC<Props> = ({ cells }) => {
|
||||||
return (
|
return (
|
||||||
cells && (
|
cells && (
|
||||||
<>
|
<>
|
||||||
@ -44,4 +44,4 @@ const ModCellList: React.FC<Props> = ({ cells }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ModCellList;
|
export default CellList;
|
@ -34,7 +34,7 @@ const CellModList: React.FC<Props> = ({ mods, counts }) => {
|
|||||||
return (
|
return (
|
||||||
mods && (
|
mods && (
|
||||||
<>
|
<>
|
||||||
<h2>Mods</h2>
|
<h2>Mods ({modsWithCounts.length})</h2>
|
||||||
<ul className={styles["mod-list"]}>
|
<ul className={styles["mod-list"]}>
|
||||||
{modsWithCounts
|
{modsWithCounts
|
||||||
.sort((a, b) => b.unique_downloads - a.unique_downloads)
|
.sort((a, b) => b.unique_downloads - a.unique_downloads)
|
||||||
|
@ -362,7 +362,12 @@ const Map: React.FC = () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
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 cells = [];
|
||||||
const cellSet = new Set<number>();
|
const cellSet = new Set<number>();
|
||||||
for (const cell of fetchedPlugin.cells) {
|
for (const cell of fetchedPlugin.cells) {
|
||||||
|
@ -3,7 +3,7 @@ import Head from "next/head";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import useSWRImmutable from "swr/immutable";
|
import useSWRImmutable from "swr/immutable";
|
||||||
|
|
||||||
import ModCellList from "./ModCellList";
|
import CellList from "./CellList";
|
||||||
import styles from "../styles/ModData.module.css";
|
import styles from "../styles/ModData.module.css";
|
||||||
|
|
||||||
export interface CellCoord {
|
export interface CellCoord {
|
||||||
@ -160,7 +160,7 @@ const ModData: React.FC<Props> = ({
|
|||||||
<strong>Unique Downloads:</strong>{" "}
|
<strong>Unique Downloads:</strong>{" "}
|
||||||
{numberFmt.format(unique_downloads)}
|
{numberFmt.format(unique_downloads)}
|
||||||
</div>
|
</div>
|
||||||
<ModCellList cells={data.cells} />
|
<CellList cells={data.cells} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,20 @@ import React, { useEffect } from "react";
|
|||||||
import useSWRImmutable from "swr/immutable";
|
import useSWRImmutable from "swr/immutable";
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector } from "../lib/hooks";
|
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 PluginModList from "./PluginModList";
|
||||||
|
import CellList from "./CellList";
|
||||||
|
import type { CellCoord } from "./ModData";
|
||||||
import PluginData, { Plugin as PluginProps } from "./PluginData";
|
import PluginData, { Plugin as PluginProps } from "./PluginData";
|
||||||
import styles from "../styles/PluginData.module.css";
|
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);
|
const res = await fetch(url);
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@ -20,18 +28,34 @@ const jsonFetcher = async (url: string): Promise<PluginsByHashWithMods | null> =
|
|||||||
return res.json();
|
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];
|
const dataPlugin = data && data.plugins.length > 0 && data.plugins[0];
|
||||||
return {
|
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,
|
size: plugin?.size || (dataPlugin && dataPlugin.size) || 0,
|
||||||
author: plugin?.parsed?.header.author || (dataPlugin && dataPlugin.author) || undefined,
|
author:
|
||||||
description: plugin?.parsed?.header.description || (dataPlugin && dataPlugin.description) || undefined,
|
plugin?.parsed?.header.author ||
|
||||||
masters: plugin?.parsed?.header.masters || (dataPlugin && dataPlugin.masters) || [],
|
(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) || "",
|
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 = {
|
type Props = {
|
||||||
hash: string;
|
hash: string;
|
||||||
@ -53,7 +77,7 @@ const PluginDetail: React.FC<Props> = ({ hash, counts }) => {
|
|||||||
if (data) {
|
if (data) {
|
||||||
dispatch(setFetchedPlugin(data));
|
dispatch(setFetchedPlugin(data));
|
||||||
}
|
}
|
||||||
}, [dispatch, data, fetchedPlugin])
|
}, [dispatch, data, fetchedPlugin]);
|
||||||
|
|
||||||
if (!plugin && error && error.status === 404) {
|
if (!plugin && error && error.status === 404) {
|
||||||
return <h3>Plugin could not be found.</h3>;
|
return <h3>Plugin could not be found.</h3>;
|
||||||
@ -67,11 +91,22 @@ const PluginDetail: React.FC<Props> = ({ hash, counts }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PluginData
|
<PluginData plugin={buildPluginProps(data, plugin)} counts={counts} />
|
||||||
plugin={buildPluginProps(data, plugin)}
|
{data && (
|
||||||
counts={counts}
|
<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} />}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,7 @@ const PluginModList: React.FC<Props> = ({ mods, files, counts }) => {
|
|||||||
return (
|
return (
|
||||||
mods && (
|
mods && (
|
||||||
<>
|
<>
|
||||||
<h2>Mods</h2>
|
<h2>Mods ({modsWithCounts.length})</h2>
|
||||||
<ul className={styles["mod-list"]}>
|
<ul className={styles["mod-list"]}>
|
||||||
{modsWithCounts
|
{modsWithCounts
|
||||||
.sort((a, b) => b.unique_downloads - a.unique_downloads)
|
.sort((a, b) => b.unique_downloads - a.unique_downloads)
|
||||||
@ -96,42 +96,39 @@ const PluginModList: React.FC<Props> = ({ mods, files, counts }) => {
|
|||||||
{numberFmt.format(mod.unique_downloads)}
|
{numberFmt.format(mod.unique_downloads)}
|
||||||
</div>
|
</div>
|
||||||
<ul className={styles["file-list"]}>
|
<ul className={styles["file-list"]}>
|
||||||
{files.filter(file => file.mod_id === mod.id).map(file => (
|
{files
|
||||||
<li key={file.id}>
|
.filter((file) => file.mod_id === mod.id)
|
||||||
<div>
|
.map((file) => (
|
||||||
<strong>File:</strong>{" "}
|
<li key={file.id}>
|
||||||
{file.name}
|
|
||||||
</div>
|
|
||||||
{file.mod_version && (
|
|
||||||
<div>
|
<div>
|
||||||
<strong>Version:</strong>{" "}
|
<strong>File:</strong> {file.name}
|
||||||
{file.mod_version}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{file.mod_version && (
|
||||||
{file.version && file.mod_version !== file.version && (
|
<div>
|
||||||
|
<strong>Version:</strong> {file.mod_version}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{file.version && file.mod_version !== file.version && (
|
||||||
|
<div>
|
||||||
|
<strong>File Version:</strong> {file.version}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{file.category && (
|
||||||
|
<div>
|
||||||
|
<strong>Category:</strong> {file.category}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div>
|
<div>
|
||||||
<strong>File Version:</strong>{" "}
|
<strong>Size:</strong> {formatBytes(file.size)}
|
||||||
{file.version}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{file.uploaded_at && (
|
||||||
{file.category && (
|
<div>
|
||||||
<div>
|
<strong>Uploaded:</strong>{" "}
|
||||||
<strong>Category:</strong>{" "}
|
{format(new Date(file.uploaded_at), "d MMM y")}
|
||||||
{file.category}
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
</li>
|
||||||
<div>
|
))}
|
||||||
<strong>Size:</strong>{" "}
|
|
||||||
{formatBytes(file.size)}
|
|
||||||
</div>
|
|
||||||
{file.uploaded_at && (
|
|
||||||
<div>
|
|
||||||
<strong>Uploaded:</strong>{" "}
|
|
||||||
{format(new Date(file.uploaded_at), "d MMM y")}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
Loading…
Reference in New Issue
Block a user