From 714ba9aae7d8c651612f586fa5dcd5996154e943 Mon Sep 17 00:00:00 2001 From: monoid Date: Fri, 8 Jan 2021 17:26:38 +0900 Subject: [PATCH] back link feature --- src/client/accessor/util.ts | 18 ++++++++++++++++++ src/client/app.tsx | 29 +++++++++++++++++------------ src/client/page/contentinfo.tsx | 31 +++++++++++++++++++++---------- src/client/page/gallery.tsx | 14 +++++++++++--- src/client/page/reader/manga.tsx | 2 +- src/client/state.tsx | 3 +++ src/server.ts | 6 ++++++ 7 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 src/client/state.tsx diff --git a/src/client/accessor/util.ts b/src/client/accessor/util.ts index 7f746b8..f9bd1ad 100644 --- a/src/client/accessor/util.ts +++ b/src/client/accessor/util.ts @@ -14,4 +14,22 @@ export const toQueryString = (obj:ToQueryStringA)=> { ? e[1].map(f=>`${e[0]}[]=${encodeURIComponent(f)}`).join('&') : `${e[0]}=${encodeURIComponent(e[1])}`) .join('&'); +} +export const QueryStringToMap = (query:string) =>{ + const keyValue = query.slice(query.indexOf("?")+1).split("&"); + const param:{[k:string]:string|string[]} = {}; + keyValue.forEach((p)=>{ + const [k,v] = p.split("="); + if(k.endsWith("[]")){ + let arr = param[k]; + if(arr instanceof Array){ + arr.push(v); + } + else{ + param[k] = [v]; + } + } + else param[k] = v; + }); + return param; } \ No newline at end of file diff --git a/src/client/app.tsx b/src/client/app.tsx index 10c1a26..d96f9af 100644 --- a/src/client/app.tsx +++ b/src/client/app.tsx @@ -1,23 +1,28 @@ -import React, { useRef, useState } from 'react'; +import React, { createContext, useRef, useState } from 'react'; import ReactDom from 'react-dom'; import {BrowserRouter, Route, Switch as RouterSwitch} from 'react-router-dom'; import { Gallery, ContentAbout} from './page/mod'; +import {BackLinkContext} from './state'; import './css/style.css'; const FooProfile = ()=>
test profile
; const App = () => { - return ( - - }> - }> - }> - - -
404 Not Found
-
-
-
); + const [path,setPath] = useState("/"); + return ( + + + + }> + }> + }> + + +
404 Not Found
+
+
+
+
); }; ReactDom.render( diff --git a/src/client/page/contentinfo.tsx b/src/client/page/contentinfo.tsx index a14112f..e178dc4 100644 --- a/src/client/page/contentinfo.tsx +++ b/src/client/page/contentinfo.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import { Redirect, Route, Switch, useHistory, useRouteMatch, match as MatchType, Link as RouterLink, useParams, useLocation } from 'react-router-dom'; import ContentAccessor, { Content } from '../accessor/contents'; import { LoadingCircle } from '../component/loading'; @@ -6,6 +6,7 @@ import { Link, Paper, makeStyles, Theme, Box, useTheme, Typography } from '@mate import {ArrowBack as ArrowBackIcon } from '@material-ui/icons'; import { MangaReader } from './reader/manga'; import { ContentInfo, Headline, NavItem, NavList } from '../component/mod'; +import {BackLinkContext} from '../state'; export const makeContentInfoUrl = (id: number) => `/doc/${id}`; export const makeMangaReaderUrl = (id: number) => `/doc/${id}/reader`; @@ -24,9 +25,15 @@ export const ContentAbout = (prop: { match: MatchType }) => { const [info, setInfo] = useState({ content: undefined, notfound:false }); const location = useLocation(); console.log("state : "+location.state); - const menu_list = ( + const menu_list = (link?:string)=>( - }> + + { + (ctx) => link === undefined ? + }/> + : }/> + } + ); @@ -42,39 +49,43 @@ export const ContentAbout = (prop: { match: MatchType }) => { }, []); if (isNaN(id)) { return ( - + Oops. Invalid ID ); } else if(info.notfound){ return ( - + Content has been removed. ) } else if (info.content === undefined) { - return ( + return ( ); } - else return ( + else{ + + return ( - + + - + - +
404 Not Found invalid url : {prop.match.path}
); + } } \ No newline at end of file diff --git a/src/client/page/gallery.tsx b/src/client/page/gallery.tsx index 00c909b..fb26106 100644 --- a/src/client/page/gallery.tsx +++ b/src/client/page/gallery.tsx @@ -1,14 +1,22 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { NavList, NavItem, Headline } from '../component/mod'; import {ArrowBack as ArrowBackIcon} from '@material-ui/icons'; import {GalleryInfo} from '../component/mod'; +import {BackLinkContext} from '../state'; +import {useLocation} from 'react-router-dom'; +import { QueryStringToMap } from '../accessor/util'; export const Gallery = ()=>{ + const location = useLocation(); + const backctx = useContext(BackLinkContext); + backctx.setPath("/"); + + const query = QueryStringToMap(location.search); const menu_list = ( - }> + {Object.keys(query).length !== 0 && }>} ); return ( - + ) } \ No newline at end of file diff --git a/src/client/page/reader/manga.tsx b/src/client/page/reader/manga.tsx index aab0f07..9eb9f3e 100644 --- a/src/client/page/reader/manga.tsx +++ b/src/client/page/reader/manga.tsx @@ -22,7 +22,7 @@ export const MangaReader = (props:{content:Content})=>{ return Error. DB error. page restriction } const page:number = additional['page'] as number; - return (
{[...Array(page).keys()].map(x=>())}
); + return (
{[...Array(page).keys()].map(x=>())}
); } export default MangaReader; \ No newline at end of file diff --git a/src/client/state.tsx b/src/client/state.tsx new file mode 100644 index 0000000..6f31cf5 --- /dev/null +++ b/src/client/state.tsx @@ -0,0 +1,3 @@ +import React, { createContext, useRef, useState } from 'react'; + +export const BackLinkContext = createContext({path:"",setPath:(s:string)=>{}}); \ No newline at end of file diff --git a/src/server.ts b/src/server.ts index d7aba7a..5a01c22 100644 --- a/src/server.ts +++ b/src/server.ts @@ -47,6 +47,12 @@ async function main(){ ctx.body = index_html; } ); + router.get('/search' + ,async (ctx,next)=>{ + ctx.type = "html"; + ctx.body = index_html; + } + ); let content_router = getContentRouter(createKnexContentsAccessor(db)); router.use('/content',content_router.routes()); router.use('/content',content_router.allowedMethods());