Added support for gestures to open close menus
This commit is contained in:
		
							parent
							
								
									76deea2aa7
								
							
						
					
					
						commit
						7dd2325e97
					
				
							
								
								
									
										17
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										17
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -12,7 +12,8 @@ | |||||||
|         "markdown-to-jsx": "^7.1.6", |         "markdown-to-jsx": "^7.1.6", | ||||||
|         "next": "^12.0.7", |         "next": "^12.0.7", | ||||||
|         "react": "17.0.2", |         "react": "17.0.2", | ||||||
|         "react-dom": "17.0.2" |         "react-dom": "17.0.2", | ||||||
|  |         "react-swipeable": "^6.2.0" | ||||||
|       }, |       }, | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "@tailwindcss/typography": "^0.5.0", |         "@tailwindcss/typography": "^0.5.0", | ||||||
| @ -3316,6 +3317,14 @@ | |||||||
|         "react": "17.0.2" |         "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": { |     "node_modules/regenerator-runtime": { | ||||||
|       "version": "0.13.4", |       "version": "0.13.4", | ||||||
|       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", |       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", | ||||||
| @ -6464,6 +6473,12 @@ | |||||||
|         "scheduler": "^0.20.2" |         "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": { |     "regenerator-runtime": { | ||||||
|       "version": "0.13.4", |       "version": "0.13.4", | ||||||
|       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", |       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", | ||||||
|  | |||||||
| @ -15,7 +15,8 @@ | |||||||
|     "markdown-to-jsx": "^7.1.6", |     "markdown-to-jsx": "^7.1.6", | ||||||
|     "next": "^12.0.7", |     "next": "^12.0.7", | ||||||
|     "react": "17.0.2", |     "react": "17.0.2", | ||||||
|     "react-dom": "17.0.2" |     "react-dom": "17.0.2", | ||||||
|  |     "react-swipeable": "^6.2.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@tailwindcss/typography": "^0.5.0", |     "@tailwindcss/typography": "^0.5.0", | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; | |||||||
| import MainPanel from "./Panels/MainPanel"; | import MainPanel from "./Panels/MainPanel"; | ||||||
| import { useState } from "react"; | import { useState } from "react"; | ||||||
| import Head from "next/head"; | import Head from "next/head"; | ||||||
|  | import { useSwipeable } from "react-swipeable"; | ||||||
| 
 | 
 | ||||||
| type AppLayoutProps = { | type AppLayoutProps = { | ||||||
|   subPanel?: React.ReactNode; |   subPanel?: React.ReactNode; | ||||||
| @ -17,6 +18,14 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | |||||||
|   const [mainPanelOpen, setMainPanelOpen] = useState(false); |   const [mainPanelOpen, setMainPanelOpen] = useState(false); | ||||||
|   const [subPanelOpen, setsubPanelOpen] = 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 = |   const mainPanelClass = | ||||||
|     "fixed desktop:left-0 desktop:top-0 desktop:bottom-0 desktop:w-[20rem]"; |     "fixed desktop:left-0 desktop:top-0 desktop:bottom-0 desktop:w-[20rem]"; | ||||||
|   const subPanelClass = |   const subPanelClass = | ||||||
| @ -34,7 +43,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <> |     <div {...handlers}> | ||||||
|       <Head> |       <Head> | ||||||
|         <title> |         <title> | ||||||
|           {props.title ? `${titlePrefix} - ${props.title}` : titlePrefix} |           {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="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"> |             <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-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> |           </div> | ||||||
|         </div> |         </div> | ||||||
| @ -99,7 +110,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { | |||||||
|       {/* Sub panel */} |       {/* Sub panel */} | ||||||
|       {props.subPanel ? ( |       {props.subPanel ? ( | ||||||
|         <div |         <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 |             turnSubIntoContent | ||||||
|               ? "mobile:mobile:translate-x-0 mobile:bottom-20 mobile:left-0 mobile:border-l-0" |               ? "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 */} |       {/* Main panel */} | ||||||
|       <div |       <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"}`}
 |         ${mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
 | ||||||
|       > |       > | ||||||
|         <MainPanel langui={props.langui} /> |         <MainPanel langui={props.langui} /> | ||||||
|       </div> |       </div> | ||||||
|     </> |     </div> | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @ -8,15 +8,17 @@ type PanelHeaderProps = { | |||||||
| 
 | 
 | ||||||
| export default function PanelHeader(props: PanelHeaderProps): JSX.Element { | export default function PanelHeader(props: PanelHeaderProps): JSX.Element { | ||||||
|   return ( |   return ( | ||||||
|     <div className="w-full grid place-items-center"> |     <> | ||||||
|       {props.icon ? ( |       <div className="w-full grid place-items-center"> | ||||||
|         <span className="material-icons !text-4xl mb-3">{props.icon}</span> |         {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> : ""} |         <h2 className="text-2xl">{props.title}</h2> | ||||||
|  |         {props.description ? <p>{props.description}</p> : ""} | ||||||
|  |       </div> | ||||||
|       <HorizontalLine /> |       <HorizontalLine /> | ||||||
|     </div> |     </> | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ import Button from "components/Button"; | |||||||
| import HorizontalLine from "components/HorizontalLine"; | import HorizontalLine from "components/HorizontalLine"; | ||||||
| import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; | import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; | ||||||
| import Markdown from "markdown-to-jsx"; | import Markdown from "markdown-to-jsx"; | ||||||
|  | import Script from "next/script"; | ||||||
| 
 | 
 | ||||||
| type MainPanelProps = { | type MainPanelProps = { | ||||||
|   langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]; |   langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]; | ||||||
| @ -15,18 +16,21 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { | |||||||
|   const langui = props.langui; |   const langui = props.langui; | ||||||
|   const router = useRouter(); |   const router = useRouter(); | ||||||
|   return ( |   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=""> | ||||||
|         <div className="grid place-items-center"> |         <div className="grid place-items-center mobile:grid-flow-col"> | ||||||
|           <Link href="/" passHref> |           <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 |               <SVG | ||||||
|                 src={"/icons/accords.svg"} |                 src={"/icons/accords.svg"} | ||||||
|                 alt={"Logo of Accord's Library"} |                 alt={"Logo of Accord's Library"} | ||||||
|               /> |               /> | ||||||
|             </div> |             </div> | ||||||
|           </Link> |           </Link> | ||||||
|           <div className="relative mt-5"> |           <div className="relative mt-5 mobile:self-start"> | ||||||
|             {router.locale ? ( |             {router.locale ? ( | ||||||
|               <Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5"> |               <Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5"> | ||||||
|                 {router.locale.toUpperCase()} |                 {router.locale.toUpperCase()} | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ type SubPanelProps = { | |||||||
| 
 | 
 | ||||||
| export default function SubPanel(props: SubPanelProps): JSX.Element { | export default function SubPanel(props: SubPanelProps): JSX.Element { | ||||||
|   return ( |   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} |       {props.children} | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
|  | |||||||
| @ -4,7 +4,6 @@ import SVG from "components/SVG"; | |||||||
| import { getWebsiteInterface } from "graphql/operations"; | import { getWebsiteInterface } from "graphql/operations"; | ||||||
| import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; | import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; | ||||||
| import { GetStaticProps } from "next"; | import { GetStaticProps } from "next"; | ||||||
| import Script from "next/script"; |  | ||||||
| type HomeProps = { | type HomeProps = { | ||||||
|   langui: GetWebsiteInterfaceQuery; |   langui: GetWebsiteInterfaceQuery; | ||||||
| }; | }; | ||||||
| @ -24,19 +23,6 @@ export default function Home(props: HomeProps): JSX.Element { | |||||||
|         <h2 className="mt-0">Discover • Analyse • Translate • Archive</h2> |         <h2 className="mt-0">Discover • Analyse • Translate • Archive</h2> | ||||||
|       </div> |       </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> |       <h2>What is this?</h2> | ||||||
|       <p> |       <p> | ||||||
|         Accord’s Library aims at gathering and archiving all of Yoko |         Accord’s Library aims at gathering and archiving all of Yoko | ||||||
|  | |||||||
| @ -50,6 +50,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { | |||||||
|       /> |       /> | ||||||
|       <HorizontalLine /> |       <HorizontalLine /> | ||||||
| 
 | 
 | ||||||
|  |       <div className="grid gap-4"> | ||||||
|       <NavOption |       <NavOption | ||||||
|         title={langui.library_item_summary} |         title={langui.library_item_summary} | ||||||
|         url="#summary" |         url="#summary" | ||||||
| @ -101,6 +102,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { | |||||||
|       ) : ( |       ) : ( | ||||||
|         "" |         "" | ||||||
|       )} |       )} | ||||||
|  |       </div> | ||||||
|     </SubPanel> |     </SubPanel> | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 DrMint
						DrMint