import React, { useState, useEffect } from "react"; import { graphql, navigate, Link } from "gatsby"; import { GatsbyImage, getImage } from "gatsby-plugin-image"; import { Helmet } from "react-helmet"; import classnames from "classnames"; import ChevronLeft from "@spectrum-icons/workflow/ChevronLeft"; import ChevronRight from "@spectrum-icons/workflow/ChevronRight"; import Calendar from "@spectrum-icons/workflow/Calendar"; import Stopwatch from "@spectrum-icons/workflow/Stopwatch"; import Exposure from "@spectrum-icons/workflow/Exposure"; import Filmroll from "@spectrum-icons/workflow/Filmroll"; import Camera from "@spectrum-icons/workflow/Camera"; import Circle from "@spectrum-icons/workflow/Circle"; import Location from "@spectrum-icons/workflow/Location"; import { getAspectRatio, getMeta, getName, getShutterFractionFromExposureTime, getVibrant, getHelmetSafeBodyStyle, hasName, getCanonicalSize, getGalleryPageUrl, } from "../../utils"; import MetadataItem from "./MetadataItem"; import Nav from "../Nav"; const logKeyShortcut = (keyCode) => { try { // eslint-disable-next-line window.plausible("KeyShortcut", { props: { keyCode } }); // eslint-disable-next-line _paq.push(["trackEvent", "GalleryImage", "KeyShortcut", keyCode]); } catch (e) { /* do nothing */ } }; const IconStyle = { width: '24px', margin: '0 4px' } const ArrowLinkClasses = `hover:underline text-vibrant-light hover:text-muted-light lg:px-4 self-stretch flex items-center hover:bg-black/50 max-h-screen sticky top-0 `; const GalleryImage = ({ data, location: { state } }) => { const { sortedImageList, currentIndex, filterKeyword, sortKey } = state ?? {}; const image = data.file; const ar = getAspectRatio(image); const [zoom, setZoom] = useState(false); const [isClient, setIsClient] = useState(true); useEffect(() => { setIsClient(true); }, []); const nextIndex = sortedImageList && currentIndex < sortedImageList.length ? currentIndex + 1 : null; const prevIndex = sortedImageList && currentIndex > 0 ? currentIndex - 1 : null; const nextImage = sortedImageList && sortedImageList[nextIndex]; const prevImage = sortedImageList && sortedImageList[prevIndex]; React.useEffect(() => { const keyListener = (e) => { switch (e.code) { case "ArrowRight": { logKeyShortcut(e.code); if (nextImage) { navigate(`/photogallery/${nextImage}/`, { state: { currentIndex: currentIndex + 1, sortedImageList, filterKeyword, sortKey, }, }); } return; } case "ArrowLeft": { logKeyShortcut(e.code); if (prevImage) { navigate(`/photogallery/${prevImage}/`, { state: { currentIndex: currentIndex - 1, sortedImageList, filterKeyword, sortKey, }, }); } return; } case "Escape": case "KeyG": { logKeyShortcut(e.code); navigate( getGalleryPageUrl({ keyword: filterKeyword, sortKey }, image.base) ); } } }; document.addEventListener("keydown", keyListener); return () => { document.removeEventListener("keydown", keyListener); }; }, [ nextImage, prevImage, image.base, currentIndex, sortedImageList, filterKeyword, sortKey, ]); const name = getName(image); const { meta, dateTaken: dt } = getMeta(image); let locationString; if (meta.City || meta.State || meta.Location) { const location = [meta.Location, meta.City, meta.State].filter(Boolean); locationString = location.join(", "); } const vibrant = getVibrant(image, true); const canonicalSize = getCanonicalSize(image); const orientationClasses = ar > 1 ? "flex-col" : "portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col"; const verticalPad = ar > 1 ? "250px" : "100px"; const shutterSpeed = React.useMemo( () => getShutterFractionFromExposureTime(meta.ExposureTime || 0), [meta] ); const dateTaken = React.useMemo(() => new Date(dt), [dt]); return ( <> {name} - Gallery | Chuck Dries
); }; export const query = graphql` query GalleryImage($imageFilename: String) { file(base: { eq: $imageFilename }) { base publicURL childImageSharp { fluid { aspectRatio } gatsbyImageData( layout: CONSTRAINED placeholder: DOMINANT_COLOR quality: 90 ) } fields { imageMeta { dateTaken meta { Make Model ExposureTime FNumber ISO DateTimeOriginal CreateDate ShutterSpeedValue ApertureValue FocalLength LensModel ObjectName Caption # Location City State } vibrant { ...VibrantColors } } } } } `; export default GalleryImage;