fix reader
This commit is contained in:
parent
714ba9aae7
commit
26bfa5785b
@ -102,8 +102,7 @@ export const ContentInfo = (props: {
|
|||||||
allTag = allTag.filter(x => !x.startsWith("artist:"));
|
allTag = allTag.filter(x => !x.startsWith("artist:"));
|
||||||
return (<Paper className={propclasses.root || rootName} elevation={4}>
|
return (<Paper className={propclasses.root || rootName} elevation={4}>
|
||||||
<Link className={propclasses.thumbnail_anchor || thumbnail_anchor} component={RouterLink} to={{
|
<Link className={propclasses.thumbnail_anchor || thumbnail_anchor} component={RouterLink} to={{
|
||||||
pathname:makeContentReaderUrl(content.id),
|
pathname:makeContentReaderUrl(content.id)
|
||||||
state:props.gallery
|
|
||||||
}}>
|
}}>
|
||||||
<ThumbnailContainer content={content}
|
<ThumbnailContainer content={content}
|
||||||
className={propclasses.thumbnail_content || thumbnail_content}/>
|
className={propclasses.thumbnail_content || thumbnail_content}/>
|
||||||
@ -111,7 +110,6 @@ export const ContentInfo = (props: {
|
|||||||
<Box className={propclasses.infoContainer || classes.infoContainer}>
|
<Box className={propclasses.infoContainer || classes.infoContainer}>
|
||||||
<Link variant='h5' color='inherit' component={RouterLink} to={{
|
<Link variant='h5' color='inherit' component={RouterLink} to={{
|
||||||
pathname: props.gallery === undefined ? makeContentReaderUrl(content.id) : makeContentInfoUrl(content.id),
|
pathname: props.gallery === undefined ? makeContentReaderUrl(content.id) : makeContentInfoUrl(content.id),
|
||||||
state:props.gallery
|
|
||||||
}}
|
}}
|
||||||
className={propclasses.title || classes.title}>
|
className={propclasses.title || classes.title}>
|
||||||
{content.title}
|
{content.title}
|
||||||
|
@ -106,8 +106,11 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||||||
|
|
||||||
export const Headline = (prop: {
|
export const Headline = (prop: {
|
||||||
children?: React.ReactNode,
|
children?: React.ReactNode,
|
||||||
navListItem?: React.ReactNode,
|
|
||||||
isLogin?: boolean,
|
isLogin?: boolean,
|
||||||
|
classes?:{
|
||||||
|
content?:string,
|
||||||
|
toolbar?:string,
|
||||||
|
},
|
||||||
menu: React.ReactNode
|
menu: React.ReactNode
|
||||||
}) => {
|
}) => {
|
||||||
const [v, setv] = useState(false);
|
const [v, setv] = useState(false);
|
||||||
@ -174,7 +177,7 @@ export const Headline = (prop: {
|
|||||||
color="inherit">
|
color="inherit">
|
||||||
<AccountCircle />
|
<AccountCircle />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
: <Button color="inherit">Login</Button>
|
: <Button color="inherit" component={RouterLink} to="/login">Login</Button>
|
||||||
}
|
}
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
</AppBar>
|
</AppBar>
|
||||||
@ -194,8 +197,8 @@ export const Headline = (prop: {
|
|||||||
</Drawer>
|
</Drawer>
|
||||||
</Hidden>
|
</Hidden>
|
||||||
</nav>
|
</nav>
|
||||||
<main className={classes.content}>
|
<main className={prop.classes?.content || classes.content}>
|
||||||
<div className={classes.toolbar}></div>
|
<div className={prop.classes?.toolbar || classes.toolbar}></div>
|
||||||
{prop.children}
|
{prop.children}
|
||||||
</main>
|
</main>
|
||||||
</div>);
|
</div>);
|
||||||
|
@ -4,7 +4,7 @@ import ContentAccessor, { Content } from '../accessor/contents';
|
|||||||
import { LoadingCircle } from '../component/loading';
|
import { LoadingCircle } from '../component/loading';
|
||||||
import { Link, Paper, makeStyles, Theme, Box, useTheme, Typography } from '@material-ui/core';
|
import { Link, Paper, makeStyles, Theme, Box, useTheme, Typography } from '@material-ui/core';
|
||||||
import {ArrowBack as ArrowBackIcon } from '@material-ui/icons';
|
import {ArrowBack as ArrowBackIcon } from '@material-ui/icons';
|
||||||
import { MangaReader } from './reader/manga';
|
import { getPresenter } from './reader/reader';
|
||||||
import { ContentInfo, Headline, NavItem, NavList } from '../component/mod';
|
import { ContentInfo, Headline, NavItem, NavList } from '../component/mod';
|
||||||
import {BackLinkContext} from '../state';
|
import {BackLinkContext} from '../state';
|
||||||
|
|
||||||
@ -16,6 +16,18 @@ type ContentState = {
|
|||||||
notfound: boolean,
|
notfound: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme:Theme)=>({
|
||||||
|
noPaddingContent:{
|
||||||
|
display:'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
flexGrow: 1,
|
||||||
|
},
|
||||||
|
noPaddingToolbar:{
|
||||||
|
flex: '0 1 auto',
|
||||||
|
...theme.mixins.toolbar,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
export const ContentAbout = (prop: { match: MatchType }) => {
|
export const ContentAbout = (prop: { match: MatchType }) => {
|
||||||
const match = useRouteMatch<{id:string}>("/doc/:id");
|
const match = useRouteMatch<{id:string}>("/doc/:id");
|
||||||
if (match == null) {
|
if (match == null) {
|
||||||
@ -36,7 +48,7 @@ export const ContentAbout = (prop: { match: MatchType }) => {
|
|||||||
</BackLinkContext.Consumer>
|
</BackLinkContext.Consumer>
|
||||||
</NavList>
|
</NavList>
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
console.log("mount content about");
|
console.log("mount content about");
|
||||||
@ -47,6 +59,8 @@ export const ContentAbout = (prop: { match: MatchType }) => {
|
|||||||
})()
|
})()
|
||||||
return ()=>{console.log("unmount content about")}
|
return ()=>{console.log("unmount content about")}
|
||||||
}, []);
|
}, []);
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
if (isNaN(id)) {
|
if (isNaN(id)) {
|
||||||
return (
|
return (
|
||||||
<Headline menu={menu_list()}>
|
<Headline menu={menu_list()}>
|
||||||
@ -68,17 +82,19 @@ export const ContentAbout = (prop: { match: MatchType }) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
const ReaderPage = getPresenter(info.content);
|
||||||
return (<Switch>
|
return (<Switch>
|
||||||
<Route exact path={`${prop.match.path}/:id`}>
|
<Route exact path={`${prop.match.path}/:id`}>
|
||||||
|
|
||||||
<Headline menu={menu_list()}>
|
<Headline menu={menu_list()}>
|
||||||
<ContentInfo content={info.content}></ContentInfo>
|
<ContentInfo content={info.content}></ContentInfo>
|
||||||
</Headline>
|
</Headline>
|
||||||
</Route>
|
</Route>
|
||||||
<Route exact path={`${prop.match.path}/:id/reader`}>
|
<Route exact path={`${prop.match.path}/:id/reader`}>
|
||||||
<Headline menu={menu_list(`${prop.match.path}/${id}`)}>
|
<Headline menu={menu_list(`${prop.match.path}/${id}`)} classes={{
|
||||||
<MangaReader content={info.content}></MangaReader>
|
content:classes.noPaddingContent,
|
||||||
|
toolbar:classes.noPaddingToolbar
|
||||||
|
}}>
|
||||||
|
<ReaderPage content={info.content}></ReaderPage>
|
||||||
</Headline>
|
</Headline>
|
||||||
</Route>
|
</Route>
|
||||||
<Route>
|
<Route>
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import React, {useState, useEffect} from 'react';
|
import React, {useState, useEffect} from 'react';
|
||||||
import {Redirect, Route ,Switch,useHistory, useRouteMatch, match as MatchType, Link as RouterLink} from 'react-router-dom';
|
import { Typography, useTheme } from '@material-ui/core';
|
||||||
import { LoadingCircle } from '../../component/loading';
|
import { Content } from '../../accessor/contents';
|
||||||
import { Link, Paper, makeStyles, Theme, Box, Typography } from '@material-ui/core';
|
|
||||||
import { Content, makeThumbnailUrl } from '../../accessor/contents';
|
|
||||||
|
|
||||||
type MangaType = "manga"|"artist cg"|"donjinshi"|"western"
|
type MangaType = "manga"|"artist cg"|"donjinshi"|"western"
|
||||||
|
|
||||||
@ -16,13 +14,35 @@ export type PresentableTag = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const MangaReader = (props:{content:Content})=>{
|
export const MangaReader = (props:{content:Content})=>{
|
||||||
|
const theme = useTheme();
|
||||||
const additional = props.content.additional;
|
const additional = props.content.additional;
|
||||||
|
const [curPage,setCurPage] = useState(0);
|
||||||
if(!('page' in additional)){
|
if(!('page' in additional)){
|
||||||
console.error("invalid content : page read fail : "+ JSON.stringify(additional));
|
console.error("invalid content : page read fail : "+ JSON.stringify(additional));
|
||||||
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 PageUP = ()=>setCurPage(Math.min(curPage + 1, page - 1));
|
||||||
const page:number = additional['page'] as number;
|
const page:number = additional['page'] as number;
|
||||||
return (<div>{[...Array(page).keys()].map(x=>(<img src={`/content/${props.content.id}/manga/${x}`} key={x} style={{maxHeight:'100%',maxWidth:'100%'}}></img>))}</div>);
|
const onKeyUp = (e: KeyboardEvent)=>{
|
||||||
|
if(e.code === "ArrowLeft"){
|
||||||
|
PageDown();
|
||||||
|
}
|
||||||
|
else if(e.code === "ArrowRight"){
|
||||||
|
PageUP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
useEffect(()=>{
|
||||||
|
document.addEventListener("keydown",onKeyUp);
|
||||||
|
return ()=>{
|
||||||
|
document.removeEventListener("keydown",onKeyUp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//theme.mixins.toolbar.minHeight;
|
||||||
|
return (<div style={{overflow: 'hidden', alignSelf:'center'}}>
|
||||||
|
<img onClick={PageUP} src={`/content/${props.content.id}/manga/${curPage}`}
|
||||||
|
style={{maxWidth:'100%', maxHeight:'calc(100vh - 64px)'}}></img>
|
||||||
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MangaReader;
|
export default MangaReader;
|
@ -1,21 +1,31 @@
|
|||||||
|
import { Typography } from '@material-ui/core';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Content, makeThumbnailUrl } from '../../accessor/contents';
|
import { Content, makeThumbnailUrl } from '../../accessor/contents';
|
||||||
import {MangaReader} from './manga';
|
import {MangaReader} from './manga';
|
||||||
|
import {VideoReader} from './video'
|
||||||
|
|
||||||
export type PresenterCollection = {
|
export interface PagePresenterProp{
|
||||||
ReaderPage: (props:{content:Content,className?:string})=> JSX.Element;
|
content:Content,
|
||||||
};
|
className?:string
|
||||||
|
}
|
||||||
|
interface PagePresenter{
|
||||||
|
(prop:PagePresenterProp):JSX.Element
|
||||||
|
}
|
||||||
|
|
||||||
export const getPresenter = (content:Content):PresenterCollection=>{
|
export const getPresenter = (content:Content):PagePresenter => {
|
||||||
return {
|
switch (content.content_type) {
|
||||||
ReaderPage:MangaReader
|
case "manga":
|
||||||
};
|
return MangaReader;
|
||||||
|
case "video":
|
||||||
|
return VideoReader;
|
||||||
|
}
|
||||||
|
return ()=><Typography variant='h2'>Not implemented reader</Typography>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ThumbnailContainer = (props:{content:Content, className?:string})=>{
|
export const ThumbnailContainer = (props:{content:Content, className?:string})=>{
|
||||||
const thumbnailurl = makeThumbnailUrl(props.content);
|
const thumbnailurl = makeThumbnailUrl(props.content);
|
||||||
if(props.content.content_type === "video"){
|
if(props.content.content_type === "video"){
|
||||||
return (<video src={thumbnailurl} className={props.className}></video>)
|
return (<video src={thumbnailurl} muted autoPlay loop className={props.className}></video>)
|
||||||
}
|
}
|
||||||
else return (<img src={thumbnailurl} className={props.className}></img>)
|
else return (<img src={thumbnailurl} className={props.className}></img>)
|
||||||
}
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Content } from '../../accessor/contents';
|
||||||
|
|
||||||
|
export const VideoReader = (props:{content:Content})=>{
|
||||||
|
const id = props.content.id;
|
||||||
|
return <video controls autoPlay src={`/content/${props.content.id}/video`} style={{maxHeight:'100%',maxWidth:'100%'}}></video>;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user