From 7dd2325e97e31274a1d102f9ce498e0731c1b3e5 Mon Sep 17 00:00:00 2001 From: DrMint Date: Thu, 17 Feb 2022 05:50:18 +0100 Subject: [PATCH] Added support for gestures to open close menus --- package-lock.json | 17 ++++- package.json | 3 +- src/components/AppLayout.tsx | 21 ++++-- .../Library/LibraryMediaPreview.tsx | 67 ------------------- .../PanelComponents/PanelHeader.tsx | 20 +++--- src/components/Panels/MainPanel.tsx | 12 ++-- src/components/Panels/SubPanel.tsx | 2 +- src/pages/index.tsx | 14 ---- src/pages/library/items/[slug].tsx | 2 + 9 files changed, 56 insertions(+), 102 deletions(-) delete mode 100644 src/components/Library/LibraryMediaPreview.tsx diff --git a/package-lock.json b/package-lock.json index cac3422..be4e0b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "markdown-to-jsx": "^7.1.6", "next": "^12.0.7", "react": "17.0.2", - "react-dom": "17.0.2" + "react-dom": "17.0.2", + "react-swipeable": "^6.2.0" }, "devDependencies": { "@tailwindcss/typography": "^0.5.0", @@ -3316,6 +3317,14 @@ "react": "17.0.2" } }, + "node_modules/react-swipeable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.2.0.tgz", + "integrity": "sha512-nWQ8dEM8e/uswZLSIkXUsAnQmnX4MTcryOHBQIQYRMJFDpgDBSiVbKsz/BZVCIScF4NtJh16oyxwaNOepR6xSw==", + "peerDependencies": { + "react": "^16.8.3 || ^17" + } + }, "node_modules/regenerator-runtime": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", @@ -6464,6 +6473,12 @@ "scheduler": "^0.20.2" } }, + "react-swipeable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.2.0.tgz", + "integrity": "sha512-nWQ8dEM8e/uswZLSIkXUsAnQmnX4MTcryOHBQIQYRMJFDpgDBSiVbKsz/BZVCIScF4NtJh16oyxwaNOepR6xSw==", + "requires": {} + }, "regenerator-runtime": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", diff --git a/package.json b/package.json index 49a507c..9316d71 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "markdown-to-jsx": "^7.1.6", "next": "^12.0.7", "react": "17.0.2", - "react-dom": "17.0.2" + "react-dom": "17.0.2", + "react-swipeable": "^6.2.0" }, "devDependencies": { "@tailwindcss/typography": "^0.5.0", diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index 1f41794..88fc4e5 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -2,6 +2,7 @@ import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; import MainPanel from "./Panels/MainPanel"; import { useState } from "react"; import Head from "next/head"; +import { useSwipeable } from "react-swipeable"; type AppLayoutProps = { subPanel?: React.ReactNode; @@ -17,6 +18,14 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { const [mainPanelOpen, setMainPanelOpen] = useState(false); const [subPanelOpen, setsubPanelOpen] = useState(false); + const handlers = useSwipeable({ + onSwipedLeft: () => + mainPanelOpen ? setMainPanelOpen(false) : props.subPanel && props.contentPanel ? setsubPanelOpen(true) : "", + onSwipedRight: () => + subPanelOpen ? setsubPanelOpen(false) : setMainPanelOpen(true), + preventDefaultTouchmoveEvent: true, + }); + const mainPanelClass = "fixed desktop:left-0 desktop:top-0 desktop:bottom-0 desktop:w-[20rem]"; const subPanelClass = @@ -34,7 +43,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { } return ( - <> +
{props.title ? `${titlePrefix} - ${props.title}` : titlePrefix} @@ -75,7 +84,9 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { <div className="grid place-content-center h-full"> <div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9"> <p className="text-4xl">❮</p> - <p className="text-2xl w-64">Select one of the options in the sidebar</p> + <p className="text-2xl w-64"> + Select one of the options in the sidebar + </p> </div> </div> </div> @@ -99,7 +110,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { {/* Sub panel */} {props.subPanel ? ( <div - className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black top-0 bottom-0 right-0 left-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-500 + className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black top-0 bottom-0 right-0 left-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 ${ turnSubIntoContent ? "mobile:mobile:translate-x-0 mobile:bottom-20 mobile:left-0 mobile:border-l-0" @@ -115,11 +126,11 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { {/* Main panel */} <div - className={`${mainPanelClass} border-r-[1px] border-black top-0 bottom-0 left-0 right-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-500 z-20 + className={`${mainPanelClass} border-r-[1px] border-black top-0 bottom-0 left-0 right-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 ${mainPanelOpen ? "" : "mobile:-translate-x-full"}`} > <MainPanel langui={props.langui} /> </div> - </> + </div> ); } diff --git a/src/components/Library/LibraryMediaPreview.tsx b/src/components/Library/LibraryMediaPreview.tsx deleted file mode 100644 index ec531d6..0000000 --- a/src/components/Library/LibraryMediaPreview.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import Link from "next/link"; -import { GetLibraryItemsPreviewQuery } from "graphql/operations-types"; -import { getAssetURL, prettyDate, prettyPrice } from "queries/helpers"; -import Image from "next/image"; - -export type LibraryContentPreviewProps = { - item: { - slug: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["slug"]; - thumbnail: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["thumbnail"]; - title: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["title"]; - subtitle: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["subtitle"]; - price?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["price"]; - release_date?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["release_date"]; - }; -}; - -export default function LibraryContentPreview( - props: LibraryContentPreviewProps -): JSX.Element { - const item = props.item; - - return ( - <Link href={"/library/media/" + item.slug} passHref> - <div className="drop-shadow-dark-xl cursor-pointer grid items-end hover:rounded-3xl [--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform"> - {item.thumbnail.data ? ( - <Image - src={getAssetURL(item.thumbnail.data.attributes.url)} - alt={item.thumbnail.data.attributes.alternativeText} - height={item.thumbnail.data.attributes.height} - width={item.thumbnail.data.attributes.width} - /> - ) : ( - <div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div> - )} - <div className="linearbg-1 drop-shadow-dark-lg absolute bottom-2 inset-x-[-0.15rem] opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-4 text-left"> - <div> - <h2 className="text-lg leading-7">{item.title}</h2> - <h3 className="leading-3">{item.subtitle}</h3> - </div> - <div className="grid grid-flow-col"> - {item.release_date ? ( - <p className="text-sm"> - <span className="material-icons !text-base translate-y-[.15em] mr-1"> - event - </span> - {prettyDate(item.release_date)} - </p> - ) : ( - "" - )} - {item.price ? ( - <p className="text-sm justify-self-end"> - <span className="material-icons !text-base translate-y-[.15em] mr-1"> - shopping_cart - </span> - {prettyPrice(item.price)} - </p> - ) : ( - "" - )} - </div> - </div> - </div> - </Link> - ); -} - diff --git a/src/components/PanelComponents/PanelHeader.tsx b/src/components/PanelComponents/PanelHeader.tsx index 2690451..94e32b3 100644 --- a/src/components/PanelComponents/PanelHeader.tsx +++ b/src/components/PanelComponents/PanelHeader.tsx @@ -8,15 +8,17 @@ type PanelHeaderProps = { export default function PanelHeader(props: PanelHeaderProps): JSX.Element { return ( - <div className="w-full grid place-items-center"> - {props.icon ? ( - <span className="material-icons !text-4xl mb-3">{props.icon}</span> - ) : ( - "" - )} - <h2 className="text-2xl">{props.title}</h2> - {props.description ? <p>{props.description}</p> : ""} + <> + <div className="w-full grid place-items-center"> + {props.icon ? ( + <span className="material-icons !text-4xl mb-3">{props.icon}</span> + ) : ( + "" + )} + <h2 className="text-2xl">{props.title}</h2> + {props.description ? <p>{props.description}</p> : ""} + </div> <HorizontalLine /> - </div> + </> ); } diff --git a/src/components/Panels/MainPanel.tsx b/src/components/Panels/MainPanel.tsx index 40d78c5..47a0e3d 100644 --- a/src/components/Panels/MainPanel.tsx +++ b/src/components/Panels/MainPanel.tsx @@ -6,6 +6,7 @@ import Button from "components/Button"; import HorizontalLine from "components/HorizontalLine"; import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; import Markdown from "markdown-to-jsx"; +import Script from "next/script"; type MainPanelProps = { langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]; @@ -15,18 +16,21 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { const langui = props.langui; const router = useRouter(); return ( - <div className="grid justify-center content-start p-8 gap-y-2 justify-items-center text-center"> + <div + id="mainPanel" + className="flex flex-col justify-center content-start p-8 gap-y-2 justify-items-center text-center" + > <div className=""> - <div className="grid place-items-center"> + <div className="grid place-items-center mobile:grid-flow-col"> <Link href="/" passHref> - <div className="w-1/2 cursor-pointer transition-[filter] hover:colorize-dark"> + <div className="mobile:w-10 mobile:self-end w-1/2 cursor-pointer transition-[filter] hover:colorize-dark"> <SVG src={"/icons/accords.svg"} alt={"Logo of Accord's Library"} /> </div> </Link> - <div className="relative mt-5"> + <div className="relative mt-5 mobile:self-start"> {router.locale ? ( <Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5"> {router.locale.toUpperCase()} diff --git a/src/components/Panels/SubPanel.tsx b/src/components/Panels/SubPanel.tsx index 8e2ea64..89f2584 100644 --- a/src/components/Panels/SubPanel.tsx +++ b/src/components/Panels/SubPanel.tsx @@ -4,7 +4,7 @@ type SubPanelProps = { export default function SubPanel(props: SubPanelProps): JSX.Element { return ( - <div className="grid p-8 gap-y-2 justify-items-center text-center"> + <div className="flex flex-col p-8 gap-y-2 justify-items-center text-center mobile:h-full"> {props.children} </div> ); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index e84d3e1..e6346f2 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -4,7 +4,6 @@ import SVG from "components/SVG"; import { getWebsiteInterface } from "graphql/operations"; import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; import { GetStaticProps } from "next"; -import Script from "next/script"; type HomeProps = { langui: GetWebsiteInterfaceQuery; }; @@ -24,19 +23,6 @@ export default function Home(props: HomeProps): JSX.Element { <h2 className="mt-0">Discover • Analyse • Translate • Archive</h2> </div> - <button id="goFS">Go fullscreen</button> - <Script - id="myScript" - strategy="afterInteractive" - dangerouslySetInnerHTML={{ - __html: ` - var goFS = document.getElementById("goFS"); - goFS.addEventListener("click", function() { - document.body.requestFullscreen(); - }, false);`, - }} - ></Script> - <h2>What is this?</h2> <p> Accord’s Library aims at gathering and archiving all of Yoko diff --git a/src/pages/library/items/[slug].tsx b/src/pages/library/items/[slug].tsx index 8b292ff..a98c416 100644 --- a/src/pages/library/items/[slug].tsx +++ b/src/pages/library/items/[slug].tsx @@ -50,6 +50,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { /> <HorizontalLine /> + <div className="grid gap-4"> <NavOption title={langui.library_item_summary} url="#summary" @@ -101,6 +102,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { ) : ( "" )} + </div> </SubPanel> );