2022-02-27 06:17:52 +00:00
|
|
|
import React from "react";
|
2022-01-24 05:59:36 +00:00
|
|
|
import { useRouter } from "next/router";
|
2022-03-15 01:28:08 +00:00
|
|
|
import Image from "next/image";
|
2022-02-27 06:17:52 +00:00
|
|
|
import { formatRelative } from "date-fns";
|
2022-01-16 07:26:17 +00:00
|
|
|
|
2022-03-15 01:28:08 +00:00
|
|
|
import arrow from "../public/img/arrow.svg";
|
|
|
|
import close from "../public/img/close.svg";
|
2022-01-19 06:06:19 +00:00
|
|
|
import CellData from "./CellData";
|
2022-01-25 05:31:25 +00:00
|
|
|
import ModData from "./ModData";
|
2022-03-11 04:41:43 +00:00
|
|
|
import PluginDetail from "./PluginDetail";
|
2022-03-03 03:19:26 +00:00
|
|
|
import DataDirPicker from "./DataDirPicker";
|
|
|
|
import PluginTxtEditor from "./PluginTxtEditor";
|
|
|
|
import PluginsList from "./PluginsList";
|
2022-01-16 07:26:17 +00:00
|
|
|
import styles from "../styles/Sidebar.module.css";
|
2022-01-19 06:06:19 +00:00
|
|
|
|
2022-01-16 07:26:17 +00:00
|
|
|
type Props = {
|
2022-01-24 05:59:36 +00:00
|
|
|
selectedCell: { x: number; y: number } | null;
|
|
|
|
clearSelectedCell: () => void;
|
2022-02-07 03:00:14 +00:00
|
|
|
setSelectedCells: (cells: { x: number; y: number }[] | null) => void;
|
2022-01-30 21:55:50 +00:00
|
|
|
counts: Record<number, [number, number, number]> | null;
|
|
|
|
countsError: Error | null;
|
2022-02-27 06:17:52 +00:00
|
|
|
open: boolean;
|
|
|
|
setOpen: (open: boolean) => void;
|
|
|
|
lastModified: string | null | undefined;
|
2022-01-16 07:26:17 +00:00
|
|
|
};
|
|
|
|
|
2022-01-30 21:55:50 +00:00
|
|
|
const Sidebar: React.FC<Props> = ({
|
|
|
|
selectedCell,
|
|
|
|
clearSelectedCell,
|
2022-02-07 03:00:14 +00:00
|
|
|
setSelectedCells,
|
2022-01-30 21:55:50 +00:00
|
|
|
counts,
|
|
|
|
countsError,
|
2022-02-27 06:17:52 +00:00
|
|
|
open,
|
|
|
|
setOpen,
|
|
|
|
lastModified,
|
2022-01-30 21:55:50 +00:00
|
|
|
}) => {
|
2022-01-24 05:59:36 +00:00
|
|
|
const router = useRouter();
|
2022-01-25 05:31:25 +00:00
|
|
|
|
|
|
|
const renderLoadError = (error: Error) => (
|
|
|
|
<div>{`Error loading live download counts: ${error.message}`}</div>
|
|
|
|
);
|
|
|
|
|
|
|
|
const renderLoading = () => <div>Loading...</div>;
|
|
|
|
|
|
|
|
const renderCellData = (selectedCell: { x: number; y: number }) => {
|
2022-01-30 21:55:50 +00:00
|
|
|
if (countsError) return renderLoadError(countsError);
|
2022-01-25 05:31:25 +00:00
|
|
|
if (!counts) return renderLoading();
|
|
|
|
|
|
|
|
return <CellData selectedCell={selectedCell} counts={counts} />;
|
|
|
|
};
|
|
|
|
|
|
|
|
const renderModData = (selectedMod: number) => {
|
2022-01-30 21:55:50 +00:00
|
|
|
if (countsError) return renderLoadError(countsError);
|
2022-01-25 05:31:25 +00:00
|
|
|
if (!counts) return renderLoading();
|
|
|
|
|
2022-02-07 03:00:14 +00:00
|
|
|
return (
|
|
|
|
<ModData
|
|
|
|
selectedMod={selectedMod}
|
|
|
|
counts={counts}
|
|
|
|
setSelectedCells={setSelectedCells}
|
|
|
|
/>
|
|
|
|
);
|
2022-01-25 05:31:25 +00:00
|
|
|
};
|
2022-01-24 05:59:36 +00:00
|
|
|
|
2022-02-27 07:25:34 +00:00
|
|
|
const renderPluginData = (plugin: string) => {
|
|
|
|
if (countsError) return renderLoadError(countsError);
|
|
|
|
if (!counts) return renderLoading();
|
|
|
|
|
2022-03-11 04:41:43 +00:00
|
|
|
return <PluginDetail hash={plugin} counts={counts} />;
|
2022-02-27 07:25:34 +00:00
|
|
|
};
|
|
|
|
|
2022-03-15 03:53:55 +00:00
|
|
|
const renderLastModified = (lastModified: string | null | undefined) => {
|
|
|
|
if (lastModified) {
|
|
|
|
return (
|
|
|
|
<div className={styles["sidebar-modified-date"]}>
|
2022-03-15 04:47:31 +00:00
|
|
|
<strong>Site last updated:</strong>{" "}
|
2022-03-15 03:53:55 +00:00
|
|
|
{formatRelative(new Date(lastModified), new Date())}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-02-27 06:17:52 +00:00
|
|
|
const renderOpenSidebar = () => {
|
|
|
|
if (selectedCell) {
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
className={styles.sidebar}
|
|
|
|
style={!open ? { display: "none" } : {}}
|
|
|
|
>
|
2022-03-15 03:53:55 +00:00
|
|
|
<div className={styles["sidebar-content"]}>
|
|
|
|
<div className={styles["sidebar-header"]}>
|
|
|
|
<button className={styles.close} onClick={onClose}>
|
|
|
|
<Image src={close} width={24} height={24} alt="close" />
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<h1 className={styles["cell-name-header"]}>
|
|
|
|
Cell {selectedCell.x}, {selectedCell.y}
|
|
|
|
</h1>
|
|
|
|
{renderCellData(selectedCell)}
|
|
|
|
{renderLastModified(lastModified)}
|
2022-02-27 06:17:52 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
} else if (router.query.mod) {
|
|
|
|
const modId = parseInt(router.query.mod as string, 10);
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
className={styles.sidebar}
|
|
|
|
style={!open ? { display: "none" } : {}}
|
|
|
|
>
|
2022-03-15 03:53:55 +00:00
|
|
|
<div className={styles["sidebar-content"]}>
|
|
|
|
<div className={styles["sidebar-header"]}>
|
|
|
|
<button className={styles.close} onClick={onClose}>
|
|
|
|
<Image src={close} width={24} height={24} alt="close" />
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
{!Number.isNaN(modId) && renderModData(modId)}
|
|
|
|
{renderLastModified(lastModified)}
|
2022-02-27 06:17:52 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2022-02-27 07:25:34 +00:00
|
|
|
} else if (router.query.plugin) {
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
className={styles.sidebar}
|
|
|
|
style={!open ? { display: "none" } : {}}
|
|
|
|
>
|
2022-03-15 03:53:55 +00:00
|
|
|
<div className={styles["sidebar-content"]}>
|
|
|
|
<div className={styles["sidebar-header"]}>
|
|
|
|
<button className={styles.close} onClick={onClose}>
|
|
|
|
<Image src={close} width={24} height={24} alt="close" />
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
{renderPluginData(
|
|
|
|
typeof router.query.plugin === "string"
|
|
|
|
? router.query.plugin
|
|
|
|
: router.query.plugin[0]
|
|
|
|
)}
|
|
|
|
{renderLastModified(lastModified)}
|
2022-02-27 07:25:34 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2022-02-27 06:17:52 +00:00
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
className={styles.sidebar}
|
|
|
|
style={!open ? { display: "none" } : {}}
|
|
|
|
>
|
2022-03-15 03:53:55 +00:00
|
|
|
<div className={styles["sidebar-content"]}>
|
2022-03-15 04:47:31 +00:00
|
|
|
<h1 className={styles.title}>Modmapper</h1>
|
2022-02-27 06:17:52 +00:00
|
|
|
<p className={styles.subheader}>
|
|
|
|
An interactive map of Skyrim mods.
|
|
|
|
</p>
|
2022-03-03 03:19:26 +00:00
|
|
|
<DataDirPicker />
|
|
|
|
<PluginTxtEditor />
|
|
|
|
<PluginsList />
|
2022-03-15 03:53:55 +00:00
|
|
|
{renderLastModified(lastModified)}
|
2022-02-27 06:17:52 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-01-16 07:26:17 +00:00
|
|
|
const onClose = () => {
|
2022-01-24 05:59:36 +00:00
|
|
|
clearSelectedCell();
|
2022-01-19 06:06:19 +00:00
|
|
|
};
|
2022-01-16 07:26:17 +00:00
|
|
|
|
2022-02-27 06:17:52 +00:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{!open ? (
|
|
|
|
<button
|
|
|
|
className={styles.open}
|
|
|
|
onClick={() => setOpen(true)}
|
|
|
|
title="Show sidebar"
|
2022-03-15 03:53:55 +00:00
|
|
|
>
|
|
|
|
<Image src={arrow} alt="show" width={16} height={16} />
|
|
|
|
</button>
|
2022-02-27 06:17:52 +00:00
|
|
|
) : (
|
|
|
|
<button
|
|
|
|
className={styles.hide}
|
|
|
|
onClick={() => setOpen(false)}
|
|
|
|
title="Hide sidebar"
|
2022-03-15 03:53:55 +00:00
|
|
|
>
|
|
|
|
<Image src={arrow} alt="hide" width={16} height={16} />
|
|
|
|
</button>
|
2022-02-27 06:17:52 +00:00
|
|
|
)}
|
|
|
|
{renderOpenSidebar()}
|
|
|
|
</>
|
|
|
|
);
|
2022-01-16 07:26:17 +00:00
|
|
|
};
|
|
|
|
|
2022-01-19 06:06:19 +00:00
|
|
|
export default Sidebar;
|