Compare commits

..

No commits in common. "e83a6bbe2b4d0480cfe04eeaadf0144f9c9ee767" and "5670a12910f4c140d826ce43903a8197440c1967" have entirely different histories.

13 changed files with 712 additions and 699 deletions

File diff suppressed because it is too large Load Diff

View File

@ -90,8 +90,7 @@ export const ContentInfo = (props: {
<Paper <Paper
sx={{ sx={{
display: "flex", display: "flex",
height: props.short ? "400px" : "auto", height: "400px",
overflow: "hidden",
[theme.breakpoints.down("sm")]: { [theme.breakpoints.down("sm")]: {
flexDirection: "column", flexDirection: "column",
alignItems: "center", alignItems: "center",
@ -129,7 +128,8 @@ export const ContentInfo = (props: {
path={document.basepath + "/" + document.filename} path={document.basepath + "/" + document.filename}
createdAt={document.created_at} createdAt={document.created_at}
deletedAt={document.deleted_at != null ? document.deleted_at : undefined} deletedAt={document.deleted_at != null ? document.deleted_at : undefined}
/> >
</ComicDetailTag>
)} )}
</Box> </Box>
{document.deleted_at != null {document.deleted_at != null
@ -138,7 +138,9 @@ export const ContentInfo = (props: {
onClick={() => { onClick={() => {
documentDelete(document.id); documentDelete(document.id);
}} }}
>Delete</Button> >
Delete
</Button>
)} )}
</Box> </Box>
</Paper> </Paper>

View File

@ -198,7 +198,8 @@ export const Headline = (prop: {
} }
}} }}
value={search} value={search}
/> >
</StyledInputBase>
</StyledSearchBar> </StyledSearchBar>
{isLogin {isLogin
? ( ? (
@ -249,10 +250,12 @@ export const Headline = (prop: {
display: "flex", display: "flex",
flexFlow: "column", flexFlow: "column",
flexGrow: 1, flexGrow: 1,
padding: "0px", padding: theme.spacing(3),
marginTop: "64px", marginTop: theme.spacing(6),
}} }}
>{prop.children} >
<div style={{}}></div>
{prop.children}
</main> </main>
</div> </div>
); );

View File

@ -1,5 +0,0 @@
import { styled } from "@mui/material";
export const PagePad = styled("div")(({theme})=>({
padding: theme.spacing(3)
}))

View File

@ -2,15 +2,12 @@ import { ArrowBack as ArrowBackIcon } from "@mui/icons-material";
import { Typography } from "@mui/material"; import { Typography } from "@mui/material";
import React from "react"; import React from "react";
import { BackItem, CommonMenuList, Headline, NavList } from "../component/mod"; import { BackItem, CommonMenuList, Headline, NavList } from "../component/mod";
import { PagePad } from "../component/pagepad";
export const NotFoundPage = () => { export const NotFoundPage = () => {
const menu = CommonMenuList(); const menu = CommonMenuList();
return ( return (
<Headline menu={menu}> <Headline menu={menu}>
<PagePad> <Typography variant="h2">404 Not Found</Typography>
<Typography variant="h2">404 Not Found</Typography>
</PagePad>
</Headline> </Headline>
); );
}; };

View File

@ -6,7 +6,6 @@ import { LoadingCircle } from "../component/loading";
import { CommonMenuList, ContentInfo, Headline } from "../component/mod"; import { CommonMenuList, ContentInfo, Headline } from "../component/mod";
import { NotFoundPage } from "./404"; import { NotFoundPage } from "./404";
import { getPresenter } from "./reader/reader"; import { getPresenter } from "./reader/reader";
import { PagePad } from "../component/pagepad";
export const makeContentInfoUrl = (id: number) => `/doc/${id}`; export const makeContentInfoUrl = (id: number) => `/doc/${id}`;
export const makeComicReaderUrl = (id: number) => `/doc/${id}/reader`; export const makeComicReaderUrl = (id: number) => `/doc/${id}/reader`;
@ -80,7 +79,7 @@ export const DocumentAbout = (prop?: {}) => {
if (match == null) { if (match == null) {
throw new Error("unreachable"); throw new Error("unreachable");
} }
const id = Number.parseInt(match.id ?? "NaN"); const id = Number.parseInt(match.id);
const [info, setInfo] = useState<DocumentState>({ doc: undefined, notfound: false }); const [info, setInfo] = useState<DocumentState>({ doc: undefined, notfound: false });
const menu_list = (link?: string) => <CommonMenuList url={link}></CommonMenuList>; const menu_list = (link?: string) => <CommonMenuList url={link}></CommonMenuList>;
@ -96,33 +95,25 @@ export const DocumentAbout = (prop?: {}) => {
if (isNaN(id)) { if (isNaN(id)) {
return ( return (
<Headline menu={menu_list()}> <Headline menu={menu_list()}>
<PagePad>
<Typography variant="h2">Oops. Invalid ID</Typography> <Typography variant="h2">Oops. Invalid ID</Typography>
</PagePad>
</Headline> </Headline>
); );
} else if (info.notfound) { } else if (info.notfound) {
return ( return (
<Headline menu={menu_list()}> <Headline menu={menu_list()}>
<PagePad>
<Typography variant="h2">Content has been removed.</Typography> <Typography variant="h2">Content has been removed.</Typography>
</PagePad>
</Headline> </Headline>
); );
} else if (info.doc === undefined) { } else if (info.doc === undefined) {
return ( return (
<Headline menu={menu_list()}> <Headline menu={menu_list()}>
<PagePad>
<LoadingCircle /> <LoadingCircle />
</PagePad>
</Headline> </Headline>
); );
} else { } else {
return ( return (
<Headline menu={menu_list()}> <Headline menu={menu_list()}>
<PagePad>
<ContentInfo document={info.doc}></ContentInfo> <ContentInfo document={info.doc}></ContentInfo>
</PagePad>
</Headline> </Headline>
); );
} }

View File

@ -3,7 +3,6 @@ import { Stack } from "@mui/material";
import React, { useContext, useEffect, useState } from "react"; import React, { useContext, useEffect, useState } from "react";
import { CommonMenuList, Headline } from "../component/mod"; import { CommonMenuList, Headline } from "../component/mod";
import { UserContext } from "../state"; import { UserContext } from "../state";
import { PagePad } from "../component/pagepad";
const useStyles = (theme: Theme) => ({ const useStyles = (theme: Theme) => ({
paper: { paper: {
@ -128,7 +127,6 @@ export function DifferencePage() {
const menu = CommonMenuList(); const menu = CommonMenuList();
return ( return (
<Headline menu={menu}> <Headline menu={menu}>
<PagePad>
{(ctx.username == "admin") {(ctx.username == "admin")
? ( ? (
<div> <div>
@ -138,7 +136,6 @@ export function DifferencePage() {
</div> </div>
) )
: <Typography variant="h2">Not Allowed : please login as an admin</Typography>} : <Typography variant="h2">Not Allowed : please login as an admin</Typography>}
</PagePad>
</Headline> </Headline>
); );
} }

View File

@ -8,7 +8,6 @@ import { toQueryString } from "../accessor/util";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { QueryStringToMap } from "../accessor/util"; import { QueryStringToMap } from "../accessor/util";
import { useIsElementInViewport } from "./reader/reader"; import { useIsElementInViewport } from "./reader/reader";
import { PagePad } from "../component/pagepad";
export type GalleryProp = { export type GalleryProp = {
option?: QueryListOption; option?: QueryListOption;
@ -71,7 +70,8 @@ export const GalleryInfo = (props: GalleryProp) => {
)} )}
{props.option.allow_tag !== undefined {props.option.allow_tag !== undefined
&& props.option.allow_tag.map(x => ( && props.option.allow_tag.map(x => (
<TagChip key={x} tagname={decodeURIComponent(x)} label={decodeURIComponent(x)}/> <TagChip key={x} tagname={decodeURIComponent(x)} label={decodeURIComponent(x)}>
</TagChip>
))} ))}
</Box> </Box>
)} )}
@ -126,9 +126,7 @@ export const Gallery = () => {
option.limit = typeof query["limit"] === "string" ? parseInt(query["limit"]) : undefined; option.limit = typeof query["limit"] === "string" ? parseInt(query["limit"]) : undefined;
return ( return (
<Headline menu={menu_list}> <Headline menu={menu_list}>
<PagePad>
<GalleryInfo diff={location.search} option={query}></GalleryInfo> <GalleryInfo diff={location.search} option={query}></GalleryInfo>
</PagePad>
</Headline> </Headline>
); );
}; };

View File

@ -16,7 +16,6 @@ import { useNavigate } from "react-router-dom";
import { CommonMenuList, Headline } from "../component/mod"; import { CommonMenuList, Headline } from "../component/mod";
import { UserContext } from "../state"; import { UserContext } from "../state";
import { doLogin as doSessionLogin } from "../state"; import { doLogin as doSessionLogin } from "../state";
import { PagePad } from "../component/pagepad";
export const LoginPage = () => { export const LoginPage = () => {
const theme = useTheme(); const theme = useTheme();
@ -49,41 +48,39 @@ export const LoginPage = () => {
const menu = CommonMenuList(); const menu = CommonMenuList();
return ( return (
<Headline menu={menu}> <Headline menu={menu}>
<PagePad> <Paper style={{ width: theme.spacing(40), padding: theme.spacing(4), alignSelf: "center" }}>
<Paper style={{ width: theme.spacing(40), padding: theme.spacing(4), alignSelf: "center" }}> <Typography variant="h4">Login</Typography>
<Typography variant="h4">Login</Typography> <div style={{ minHeight: theme.spacing(2) }}></div>
<form style={{ display: "flex", flexFlow: "column", alignItems: "stretch" }}>
<TextField
label="username"
onChange={(e) => setUserLoginInfo({ ...userLoginInfo, username: e.target.value ?? "" })}
>
</TextField>
<TextField
label="password"
type="password"
onKeyDown={(e) => {
if (e.key === "Enter") doLogin();
}}
onChange={(e) => setUserLoginInfo({ ...userLoginInfo, password: e.target.value ?? "" })}
/>
<div style={{ minHeight: theme.spacing(2) }}></div> <div style={{ minHeight: theme.spacing(2) }}></div>
<form style={{ display: "flex", flexFlow: "column", alignItems: "stretch" }}> <div style={{ display: "flex" }}>
<TextField <Button onClick={doLogin}>login</Button>
label="username" <Button>signin</Button>
onChange={(e) => setUserLoginInfo({ ...userLoginInfo, username: e.target.value ?? "" })} </div>
> </form>
</TextField> </Paper>
<TextField <Dialog open={openDialog.open} onClose={handleDialogClose}>
label="password" <DialogTitle>Login Failed</DialogTitle>
type="password" <DialogContent>
onKeyDown={(e) => { <DialogContentText>detail : {openDialog.message}</DialogContentText>
if (e.key === "Enter") doLogin(); </DialogContent>
}} <DialogActions>
onChange={(e) => setUserLoginInfo({ ...userLoginInfo, password: e.target.value ?? "" })} <Button onClick={handleDialogClose} color="primary" autoFocus>Close</Button>
/> </DialogActions>
<div style={{ minHeight: theme.spacing(2) }}></div> </Dialog>
<div style={{ display: "flex" }}>
<Button onClick={doLogin}>login</Button>
<Button>signin</Button>
</div>
</form>
</Paper>
<Dialog open={openDialog.open} onClose={handleDialogClose}>
<DialogTitle>Login Failed</DialogTitle>
<DialogContent>
<DialogContentText>detail : {openDialog.message}</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleDialogClose} color="primary" autoFocus>Close</Button>
</DialogActions>
</Dialog>
</PagePad>
</Headline> </Headline>
); );
}; };

View File

@ -16,7 +16,6 @@ import {
import React, { useContext, useState } from "react"; import React, { useContext, useState } from "react";
import { CommonMenuList, Headline } from "../component/mod"; import { CommonMenuList, Headline } from "../component/mod";
import { UserContext } from "../state"; import { UserContext } from "../state";
import { PagePad } from "../component/pagepad";
const useStyles = (theme: Theme) => ({ const useStyles = (theme: Theme) => ({
paper: { paper: {
@ -78,74 +77,71 @@ export function ProfilePage() {
}; };
return ( return (
<Headline menu={menu}> <Headline menu={menu}>
<PagePad> <Paper /*className={classes.paper}*/>
<Grid container direction="column" alignItems="center">
<Paper /*className={classes.paper}*/> <Grid item>
<Grid container direction="column" alignItems="center"> <Typography variant="h4">{userctx.username}</Typography>
<Grid item>
<Typography variant="h4">{userctx.username}</Typography>
</Grid>
<Divider></Divider>
<Grid item>
Permission
</Grid>
<Grid item>
{permission_list.length == 0 ? "-" : permission_list}
</Grid>
<Grid item>
<Button onClick={handle_open}>Password Reset</Button>
</Grid>
</Grid> </Grid>
</Paper> <Divider></Divider>
<Dialog open={pw_open} onClose={handle_close}> <Grid item>
<DialogTitle>Password Reset</DialogTitle> Permission
<DialogContent> </Grid>
<Typography>type the old and new password</Typography> <Grid item>
<div /*className={classes.formfield}*/> {permission_list.length == 0 ? "-" : permission_list}
{(!isElectronContent) && ( </Grid>
<TextField <Grid item>
autoFocus <Button onClick={handle_open}>Password Reset</Button>
margin="dense" </Grid>
type="password" </Grid>
label="old password" </Paper>
value={oldpw} <Dialog open={pw_open} onClose={handle_close}>
onChange={(e) => setOldpw(e.target.value)} <DialogTitle>Password Reset</DialogTitle>
> <DialogContent>
</TextField> <Typography>type the old and new password</Typography>
)} <div /*className={classes.formfield}*/>
{(!isElectronContent) && (
<TextField <TextField
autoFocus
margin="dense" margin="dense"
type="password" type="password"
label="new password" label="old password"
value={newpw} value={oldpw}
onChange={e => setNewpw(e.target.value)} onChange={(e) => setOldpw(e.target.value)}
> >
</TextField> </TextField>
<TextField )}
margin="dense" <TextField
type="password" margin="dense"
label="new password check" type="password"
value={newpwch} label="new password"
onChange={e => setNewpwch(e.target.value)} value={newpw}
> onChange={e => setNewpw(e.target.value)}
</TextField> >
</div> </TextField>
</DialogContent> <TextField
<DialogActions> margin="dense"
<Button onClick={handle_close} color="primary">Cancel</Button> type="password"
<Button onClick={handle_ok} color="primary">Ok</Button> label="new password check"
</DialogActions> value={newpwch}
</Dialog> onChange={e => setNewpwch(e.target.value)}
<Dialog open={msg_dialog.opened} onClose={() => set_msg_dialog({ opened: false, msg: "" })}> >
<DialogTitle>Alert!</DialogTitle> </TextField>
<DialogContent> </div>
<DialogContentText>{msg_dialog.msg}</DialogContentText> </DialogContent>
</DialogContent> <DialogActions>
<DialogActions> <Button onClick={handle_close} color="primary">Cancel</Button>
<Button onClick={() => set_msg_dialog({ opened: false, msg: "" })} color="primary">Close</Button> <Button onClick={handle_ok} color="primary">Ok</Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</PagePad> <Dialog open={msg_dialog.opened} onClose={() => set_msg_dialog({ opened: false, msg: "" })}>
<DialogTitle>Alert!</DialogTitle>
<DialogContent>
<DialogContentText>{msg_dialog.msg}</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={() => set_msg_dialog({ opened: false, msg: "" })} color="primary">Close</Button>
</DialogActions>
</Dialog>
</Headline> </Headline>
); );
} }

View File

@ -1,4 +1,4 @@
import { Typography, styled } from "@mui/material"; import { Typography, useTheme } from "@mui/material";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Document } from "../../accessor/document"; import { Document } from "../../accessor/document";
@ -13,21 +13,6 @@ export type PresentableTag = {
tags: string[]; tags: string[];
}; };
const ViewMain = styled("div")(({ theme }) => ({
overflow: "hidden",
width: "100%",
height: "calc(100vh - 64px)",
position: "relative",
}));
const CurrentView = styled("img")(({theme})=>({
maxWidth: "100%",
maxHeight: "100%",
top:"50%",
left:"50%",
transform: "translate(-50%,-50%)",
position: "absolute"
}));
export const ComicReader = (props: { doc: Document }) => { export const ComicReader = (props: { doc: Document }) => {
const additional = props.doc.additional; const additional = props.doc.additional;
const [curPage, setCurPage] = useState(0); const [curPage, setCurPage] = useState(0);
@ -36,13 +21,13 @@ export const ComicReader = (props: { doc: Document }) => {
return <Typography>Error. DB error. page restriction</Typography>; return <Typography>Error. DB error. page restriction</Typography>;
} }
const PageDown = () => setCurPage(Math.max(curPage - 1, 0)); const PageDown = () => setCurPage(Math.max(curPage - 1, 0));
const PageUp = () => setCurPage(Math.min(curPage + 1, page - 1)); const PageUP = () => setCurPage(Math.min(curPage + 1, page - 1));
const page: number = additional["page"] as number; const page: number = additional["page"] as number;
const onKeyUp = (e: KeyboardEvent) => { const onKeyUp = (e: KeyboardEvent) => {
if (e.code === "ArrowLeft") { if (e.code === "ArrowLeft") {
PageDown(); PageDown();
} else if (e.code === "ArrowRight") { } else if (e.code === "ArrowRight") {
PageUp(); PageUP();
} }
}; };
useEffect(() => { useEffect(() => {
@ -53,14 +38,14 @@ export const ComicReader = (props: { doc: Document }) => {
}); });
// theme.mixins.toolbar.minHeight; // theme.mixins.toolbar.minHeight;
return ( return (
<ViewMain> <div style={{ overflow: "hidden", alignSelf: "center" }}>
<div onClick={PageDown} style={{left:"0", width: "50%", position:"absolute", height: "100%", zIndex:100}}></div> <img
<CurrentView onClick={PageUP}
onClick={PageUp}
src={`/api/doc/${props.doc.id}/comic/${curPage}`} src={`/api/doc/${props.doc.id}/comic/${curPage}`}
></CurrentView> style={{ maxWidth: "100%", maxHeight: "calc(100vh - 64px)" }}
<div onClick={PageUp} style={{right:"0", width: "50%", position:"absolute", height: "100%", zIndex:100}}></div> >
</ViewMain> </img>
</div>
); );
}; };

View File

@ -2,17 +2,14 @@ import { ArrowBack as ArrowBackIcon } from "@mui/icons-material";
import { Paper, Typography } from "@mui/material"; import { Paper, Typography } from "@mui/material";
import React from "react"; import React from "react";
import { BackItem, CommonMenuList, Headline, NavList } from "../component/mod"; import { BackItem, CommonMenuList, Headline, NavList } from "../component/mod";
import { PagePad } from "../component/pagepad";
export const SettingPage = () => { export const SettingPage = () => {
const menu = CommonMenuList(); const menu = CommonMenuList();
return ( return (
<Headline menu={menu}> <Headline menu={menu}>
<PagePad> <Paper>
<Paper> <Typography variant="h2">Setting</Typography>
<Typography variant="h2">Setting</Typography> </Paper>
</Paper>
</PagePad>
</Headline> </Headline>
); );
}; };

View File

@ -3,7 +3,6 @@ import { DataGrid, GridColDef } from "@mui/x-data-grid";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { LoadingCircle } from "../component/loading"; import { LoadingCircle } from "../component/loading";
import { CommonMenuList, Headline } from "../component/mod"; import { CommonMenuList, Headline } from "../component/mod";
import { PagePad } from "../component/pagepad";
type TagCount = { type TagCount = {
tag_name: string; tag_name: string;
@ -68,9 +67,7 @@ export const TagsPage = () => {
const menu = CommonMenuList(); const menu = CommonMenuList();
return ( return (
<Headline menu={menu}> <Headline menu={menu}>
<PagePad> <TagTable></TagTable>
<TagTable></TagTable>
</PagePad>
</Headline> </Headline>
); );
}; };