120 lines
3.7 KiB
TypeScript
120 lines
3.7 KiB
TypeScript
import { Theme, Typography } from "@mui/material";
|
|
import React, { useEffect, useState } from "react";
|
|
import { Route, Routes, useLocation, useParams } from "react-router-dom";
|
|
import DocumentAccessor, { Document } from "../accessor/document";
|
|
import { LoadingCircle } from "../component/loading";
|
|
import { CommonMenuList, ContentInfo, Headline } from "../component/mod";
|
|
import { NotFoundPage } from "./404";
|
|
import { getPresenter } from "./reader/reader";
|
|
|
|
export const makeContentInfoUrl = (id: number) => `/doc/${id}`;
|
|
export const makeComicReaderUrl = (id: number) => `/doc/${id}/reader`;
|
|
|
|
type DocumentState = {
|
|
doc: Document | undefined;
|
|
notfound: boolean;
|
|
};
|
|
|
|
const styles = (theme: Theme) => ({
|
|
noPaddingContent: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
flexGrow: 1,
|
|
},
|
|
noPaddingToolbar: {
|
|
flex: "0 1 auto",
|
|
...theme.mixins.toolbar,
|
|
},
|
|
});
|
|
|
|
export function ReaderPage(props?: {}) {
|
|
const location = useLocation();
|
|
const match = useParams<{ id: string }>();
|
|
if (match == null) {
|
|
throw new Error("unreachable");
|
|
}
|
|
const id = Number.parseInt(match.id ?? "NaN");
|
|
const [info, setInfo] = useState<DocumentState>({ doc: undefined, notfound: false });
|
|
const menu_list = (link?: string) => <CommonMenuList url={link}></CommonMenuList>;
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
if (!isNaN(id)) {
|
|
const c = await DocumentAccessor.findById(id);
|
|
setInfo({ doc: c, notfound: c === undefined });
|
|
}
|
|
})();
|
|
}, []);
|
|
|
|
if (isNaN(id)) {
|
|
return (
|
|
<Headline menu={menu_list()}>
|
|
<Typography variant="h2">Oops. Invalid ID</Typography>
|
|
</Headline>
|
|
);
|
|
} else if (info.notfound) {
|
|
return (
|
|
<Headline menu={menu_list()}>
|
|
<Typography variant="h2">Content has been removed.</Typography>
|
|
</Headline>
|
|
);
|
|
} else if (info.doc === undefined) {
|
|
return (
|
|
<Headline menu={menu_list()}>
|
|
<LoadingCircle />
|
|
</Headline>
|
|
);
|
|
} else {
|
|
const ReaderPage = getPresenter(info.doc);
|
|
return (
|
|
<Headline menu={menu_list(location.pathname)}>
|
|
<ReaderPage doc={info.doc}></ReaderPage>
|
|
</Headline>
|
|
);
|
|
}
|
|
}
|
|
|
|
export const DocumentAbout = (prop?: {}) => {
|
|
const match = useParams<{ id: string }>();
|
|
if (match == null) {
|
|
throw new Error("unreachable");
|
|
}
|
|
const id = Number.parseInt(match.id);
|
|
const [info, setInfo] = useState<DocumentState>({ doc: undefined, notfound: false });
|
|
const menu_list = (link?: string) => <CommonMenuList url={link}></CommonMenuList>;
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
if (!isNaN(id)) {
|
|
const c = await DocumentAccessor.findById(id);
|
|
setInfo({ doc: c, notfound: c === undefined });
|
|
}
|
|
})();
|
|
}, []);
|
|
|
|
if (isNaN(id)) {
|
|
return (
|
|
<Headline menu={menu_list()}>
|
|
<Typography variant="h2">Oops. Invalid ID</Typography>
|
|
</Headline>
|
|
);
|
|
} else if (info.notfound) {
|
|
return (
|
|
<Headline menu={menu_list()}>
|
|
<Typography variant="h2">Content has been removed.</Typography>
|
|
</Headline>
|
|
);
|
|
} else if (info.doc === undefined) {
|
|
return (
|
|
<Headline menu={menu_list()}>
|
|
<LoadingCircle />
|
|
</Headline>
|
|
);
|
|
} else {
|
|
return (
|
|
<Headline menu={menu_list()}>
|
|
<ContentInfo document={info.doc}></ContentInfo>
|
|
</Headline>
|
|
);
|
|
}
|
|
};
|