From 9a3d450cbc5b389bca9d94d409de2d7ab5c5d564 Mon Sep 17 00:00:00 2001 From: Ingun Jon Date: Sun, 20 Mar 2022 03:21:44 +0900 Subject: [PATCH] author, resolve prefix url, book card --- .gitignore | 2 ++ gatsby-config.js | 1 + package.json | 4 +-- src/decoders.ts | 1 + src/pages/recursive.tsx | 50 +++++++++++++++++++++++++++++++++--- src/pages/root.tsx | 3 ++- src/pages/share-dialogue.tsx | 3 ++- src/util.ts | 26 +++++++++++++++++++ 8 files changed, 82 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 35fc460..6891fd5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ node_modules/ .cache/ public .idea +/static/db/ +/static/imgs/ diff --git a/gatsby-config.js b/gatsby-config.js index f27cd77..a938b20 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -3,4 +3,5 @@ module.exports = { siteUrl: `https://www.yourdomain.tld`, }, plugins: [`gatsby-plugin-react-helmet`], + pathPrefix: `/answers`, }; diff --git a/package.json b/package.json index e244b66..3c242fa 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "scripts": { "develop": "gatsby develop", "start": "gatsby develop", - "build": "gatsby build", - "serve": "gatsby serve", + "build": "gatsby build --prefix-paths", + "serve": "gatsby serve --prefix-paths", "clean": "gatsby clean" }, "dependencies": { diff --git a/src/decoders.ts b/src/decoders.ts index 4d07bab..c230a76 100644 --- a/src/decoders.ts +++ b/src/decoders.ts @@ -4,6 +4,7 @@ export const Item = struct({ attr: partial({ q: string, a: string, + author: string, }), sha1: string, }); diff --git a/src/pages/recursive.tsx b/src/pages/recursive.tsx index 48d556b..fbfd18e 100644 --- a/src/pages/recursive.tsx +++ b/src/pages/recursive.tsx @@ -1,12 +1,12 @@ import * as React from "react"; +import { useEffect, useState } from "react"; import { TreeTem, TreeTemT } from "../decoders"; import Accordion from "@mui/material/Accordion"; import AccordionSummary from "@mui/material/AccordionSummary"; import AccordionDetails from "@mui/material/AccordionDetails"; import Typography from "@mui/material/Typography"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; -import { useEffect, useState } from "react"; -import { either } from "fp-ts"; +import { array, either } from "fp-ts"; import MathMD from "./mathmd"; import Divider from "@mui/material/Divider"; import IconButton from "@mui/material/IconButton"; @@ -14,6 +14,14 @@ import IconButton from "@mui/material/IconButton"; import ShareIcon from "@mui/icons-material/Share"; import { useAppDispatch } from "../state/hooks"; import { sha1Slice } from "../state/slice"; +import Stack from "@mui/material/Stack"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import { pipe } from "fp-ts/function"; +import { pair, relPath, relURL } from "../util"; +import { fst, snd } from "fp-ts/Tuple"; +import CardActionArea from "@mui/material/CardActionArea"; + type State = | { type: "loading"; @@ -26,12 +34,13 @@ type State = type: "error"; msg: string; }; + export default function Recursive(props: { sha1: string }) { const [state, setState] = useState({ type: "loading" }); const dispatch = useAppDispatch(); useEffect(() => { - fetch("/db/" + props.sha1 + ".json") + fetch(relPath("db", props.sha1 + ".json")) .then((x) => x.json()) .then(TreeTem.decode) .then( @@ -54,12 +63,45 @@ export default function Recursive(props: { sha1: string }) { return
{state.msg}
; case "treeTem": const { treeTem } = state; + const { left: nonBooks, right: books } = pipe( + treeTem.kids, + array.map((kid) => + kid.attr.author === undefined + ? either.left(kid) + : either.right(pair(kid.attr.author, kid)) + ), + array.separate + ); return (
{treeTem.item.attr.q && } {treeTem.item.attr.a && } - {treeTem.kids.map((item) => ( + + + {books.map((item) => ( + + { + window.location.href = + relURL() + + ("?" + + new URLSearchParams({ + sha1: snd(item).sha1, + }).toString()); + }} + > + + + {snd(item).title} + + {fst(item)} + + + + ))} + + {nonBooks.map((item) => ( window.location.replace(window.location.origin)} + onClick={() => (window.location.href = relURL().toString())} style={{ cursor: "pointer" }} > My Answers to Math Books diff --git a/src/pages/share-dialogue.tsx b/src/pages/share-dialogue.tsx index cfc72bb..3fc2e03 100644 --- a/src/pages/share-dialogue.tsx +++ b/src/pages/share-dialogue.tsx @@ -6,6 +6,7 @@ import { sha1Slice } from "../state/slice"; import Stack from "@mui/material/Stack"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; +import { relURL } from "../util"; export default function ShareDialogue() { const shareSha1 = useAppSelector((state) => state.sha1.sha1); @@ -13,7 +14,7 @@ export default function ShareDialogue() { let link = ""; if (typeof window !== "undefined") { - const url = new URL(window.location.href); + const url = relURL(); url.searchParams.append("sha1", shareSha1); link = url.toString(); } diff --git a/src/util.ts b/src/util.ts index e69de29..d0b2a8a 100644 --- a/src/util.ts +++ b/src/util.ts @@ -0,0 +1,26 @@ +export function pair(a: A, b: B): [A, B] { + return [a, b]; +} + +function joinSlash(x: string, y: string) { + if (x.endsWith("/")) { + if (y.startsWith("/")) return x + y.slice(1); + else return x + y; + } else { + if (y.startsWith("/")) return x + y; + else return x + "/" + y; + } +} +function joinSlashs(...xs: string[]) { + return xs.reduce(joinSlash); +} + +export function relPath(...xs: string[]) { + return joinSlashs(window.location.pathname, ...xs); +} + +export function relURL(...xs: string[]) { + const u = new URL(window.location.origin); + u.pathname = relPath(...xs); + return u; +}